<!DOCTYPE html>
<html lang="en">

<!-- Head tag (contains Google-Analytics、Baidu-Tongji)-->
<head>
  <!-- Google Analytics -->
  

  <!-- Baidu Tongji -->
  
    <script type="text/javascript">
      // Originial
      var _hmt = _hmt || [];
      (function () {
        var hm = document.createElement("script");
        hm.src = "https://hm.baidu.com/hm.js?cdf616a127124dd7ff798963125b304d";
        var s = document.getElementsByTagName("script")[0];
        s.parentNode.insertBefore(hm, s);
      })();
    </script>
  

  <!-- Baidu Push -->
  
    <script>
      (function () {
        var bp = document.createElement('script');
        var curProtocol = window.location.protocol.split(':')[0];
        if (curProtocol === 'https') {
          bp.src = 'https://zz.bdstatic.com/linksubmit/push.js';
        } else {
          bp.src = 'http://push.zhanzhang.baidu.com/push.js';
        }
        var s = document.getElementsByTagName("script")[0];
        s.parentNode.insertBefore(bp, s);
      })();
    </script>
  

  <meta charset="utf-8"/>
  <meta http-equiv="X-UA-Compatible" content="IE=edge"/>

  <meta name="google-site-verification" content="lxDfCplOZbIzjhG34NuQBgu2gdyRlAtMB4utP5AgEBc"/>
  <meta name="baidu-site-verification" content="PpzM9WxOJU"/>

  <meta name="viewport" content="width=device-width, initial-scale=1"/>
  <meta name="description" content="It&#39;s an IT blog..."/>
  <meta name="keyword" content="zhuang,IT  blog,Blog"/>
  <link rel="shortcut icon" href="/img/avatar/java-head.png"/>

  <!-- Place this tag in your head or just before your close body tag. -->
  <script async="async" defer="defer" src="https://buttons.github.io/buttons.js"></script>

  
    <!-- Bootstrap Core CSS -->
    <link rel="stylesheet" href="/css/bootstrap.min.css"/>

    <!-- Custom CSS -->
    <link rel="stylesheet" href="/css/beantech.min.css"/>

    <!-- Pygments Highlight CSS -->
    <link rel="stylesheet" href="/css/highlight.css"/>
    <link rel="stylesheet" href="/css/widget.css"/>
    <link rel="stylesheet" href="/css/rocket.css"/>
    <link rel="stylesheet" href="/css/signature.css"/>
    <link rel="stylesheet" href="/css/catalog.css"/>
    <link rel="stylesheet" href="/css/livemylife.css"/>

    
      <!-- wave start -->
      <link rel="stylesheet" href="/css/wave.css"/>
      <!-- wave end -->
    

    
      <!-- top start (article top hot config) -->
      <link rel="stylesheet" href="/css/top.css"/>
      <!-- top end -->
    

    
      <!-- ThemeColor start -->
      <link rel="stylesheet" href="/css/scroll.css"/>
      <!-- ThemeColor end -->
    

    
      <!-- viewer start (Picture preview) -->
      <link rel="stylesheet" href="/css/viewer.min.css"/>
      <!-- viewer end -->
    

    
      <!-- Search start -->
      <link rel="stylesheet" href="/css/search.css"/>
      <!-- Search end -->
    

    
      <!-- ThemeColor start -->
      <link rel="stylesheet" href="/css/themecolor.css"/>
      <!-- ThemeColor end -->
    

    

    
  

  <!-- Custom Fonts -->
  <!-- <link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css" rel="stylesheet" type="text/css"> -->
  <!-- Hux change font-awesome CDN to qiniu -->
  <link rel="stylesheet" href="https://cdn.staticfile.org/font-awesome/4.5.0/css/font-awesome.min.css" type="text/css">
  <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">

  <!-- Hux Delete, sad but pending in China <link href='http://fonts.googleapis.com/css?family=Lora:400,700,400italic,700italic' rel='stylesheet' type='text/css'> <link
  href='http://fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800' rel='stylesheet' type='text/ css'> -->

  <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
  <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
  <!--[if lt IE 9]> <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script> <script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script> <![endif]-->

  <!-- ga & ba script hoook -->
  <link rel="canonical" href="http://yoursite-url/cn/jvm/JVM类加载与字节码技术/">
  <title>
    
      JVM类加载与字节码技术 - either thin | or die
    
  </title>
<meta name="generator" content="Hexo 5.4.0"></head>


<!-- hack iOS CSS :active style -->

	<body ontouchstart="" class="body--light body--dark">


		<!-- ThemeColor -->
		
		<!-- ThemeColor -->
<style type="text/css">
  .body--light {
    --light-mode: none;
    --dark-mode: block;
  }
  .body--dark {
    --light-mode: block;
    --dark-mode: none;
  }
  i.mdui-icon.material-icons.light-mode {
    display: var(--light-mode);
  }
  i.mdui-icon.material-icons.dark-mode {
    display: var(--dark-mode);
  }
</style>
<div class="toggle" onclick="document.body.classList.toggle('body--dark')">
  <i class="mdui-icon material-icons light-mode"></i>
  <i class="mdui-icon material-icons dark-mode"></i>
</div>
<script>
  //getCookieValue
  function getCookieValue(a) {
    var b = document.cookie.match('(^|[^;]+)\\s*' + a + '\\s*=\\s*([^;]+)');
    return b
      ? b.pop()
      : '';
  }
  let themeMode = 'dark';
  if (getCookieValue('sb-color-mode') && (getCookieValue('sb-color-mode') !== themeMode)) {
    let dbody = document.body.classList;
    themeMode === 'dark' ? dbody.remove('body--dark') : dbody.add('body--dark');
  }

  //setCookieValue
  var toggleBtn = document.querySelector(".toggle");
  toggleBtn.addEventListener("click", function () {
    var e = document.body.classList.contains("body--dark");
    var cookieString = e
      ? "dark"
      : "light";
    var exp = new Date();
    exp.setTime(exp.getTime() + 3 * 24 * 60 * 60 * 1000); //3天过期
    document.cookie = "sb-color-mode=" + cookieString + ";expires=" + exp.toGMTString() + ";path=/";
  });
</script>

		

		<!-- Gitter -->
		

		<!-- Navigation (contains search)-->
		<!-- Navigation -->
<nav class="navbar navbar-default navbar-custom navbar-fixed-top">
  <div class="container-fluid">
    <!-- Brand and toggle get grouped for better mobile display -->
    <div class="navbar-header page-scroll">
      <button type="button" class="navbar-toggle">
        <span class="sr-only">Toggle navigation</span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
      </button>
      <a class="navbar-brand" href="/">平平淡淡</a>
    </div>

    <!-- Collect the nav links, forms, and other content for toggling -->
    <!-- Known Issue, found by Hux: <nav>'s height woule be hold on by its content. so, when navbar scale out, the <nav> will cover tags. also mask any touch event of tags, unfortunately. -->
    <div id="huxblog_navbar">
      <div class="navbar-collapse">
        <ul class="nav navbar-nav navbar-right">
          <li>
            <a href="/">首页</a>
          </li>

          
          
          
          
          <li>
            <a href="/archive/">
              
              归档
              
              
            </a>
          </li>
          
          
          
          <li>
            <a href="/tags/">
              
              标签
              
              
            </a>
          </li>
          
          
          
          <li>
            <a href="/categories/">
              
              分类
              
              
            </a>
          </li>
          
          
          
          <li>
            <a href="/about/">
              
              关于
              
              
            </a>
          </li>
          
          

          
          <li>
            <a class="popup-trigger">
              <span class="search-icon"></span>搜索</a>
          </li>
          

          <!-- LangSelect -->
          
        </ul>
      </div>
    </div>
    <!-- /.navbar-collapse -->
  </div>
  <!-- /.container -->
</nav>
<!-- progress -->
<div id="progress">
  <div class="line" style="width: 0%;"></div>
</div>

<script>
  // Drop Bootstarp low-performance Navbar Use customize navbar with high-quality material design animation in high-perf jank-free CSS3 implementation
  var $body = document.body;
  var $toggle = document.querySelector('.navbar-toggle');
  var $navbar = document.querySelector('#huxblog_navbar');
  var $collapse = document.querySelector('.navbar-collapse');

  $toggle.addEventListener('click', handleMagic)

  function handleMagic(e) {
    if ($navbar.className.indexOf('in') > 0) {
      // CLOSE
      $navbar.className = " ";
      // wait until animation end.
      setTimeout(function() {
        // prevent frequently toggle
        if ($navbar.className.indexOf('in') < 0) {
          $collapse.style.height = "0px"
        }
      }, 400)
    } else {
      // OPEN
      $collapse.style.height = "auto"
      $navbar.className += " in";
    }
  }
</script>


		<!-- Post Header (contains intro-header、signature、wordcount、busuanzi、waveoverlay) -->
		<!-- Modified by Yu-Hsuan Yen -->
<!-- Post Header -->

  <style type="text/css">
    .body--light {
      /* intro-header */
      --intro-header-background-image-url-home: url('/img/header_img/home_bg1.jpg');
      --intro-header-background-image-url-post: url('/img/header_img/lml_bg.jpg');
      --intro-header-background-image-url-page: url('//img/header_img/lml_bg.jpg');
    }
    .body--dark {
      --intro-header-background-image-url-home: linear-gradient(rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.2)), url('/img/header_img/home_bg1.jpg');
      --intro-header-background-image-url-post: linear-gradient(rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.2)), url('/img/header_img/lml_bg.jpg');
      --intro-header-background-image-url-page: linear-gradient(rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.2)), url('//img/header_img/lml_bg.jpg');
    }

    header.intro-header {
       /*post*/
        background-image: var(--intro-header-background-image-url-post);
        /* background-image: url('/img/header_img/lml_bg.jpg'); */
      
    }

    
      #signature {/*signature*/
        background-image: url('/img/signature/signature.png');
      }
    
  </style>





<header class="intro-header">
  <!-- Signature -->
  <div id="signature">
    <div class="container">
      <div class="row">
        <div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1">
          
          <div class="post-heading">
            <div class="tags">
              
              <a class="tag" href="/tags/#java" title="java">java</a>
              
              <a class="tag" href="/tags/#jvm" title="jvm">jvm</a>
              
            </div>
            <h1>JVM类加载与字节码技术</h1>
            <h2 class="subheading"></h2>
            <span class="meta">
              Posted by zhuang on
              2021-10-27
            </span>


            
            <!-- WordCount start -->
            <div class="blank_box"></div>
            <span class="meta">
              Estimated Reading Time <span class="post-count">54</span> Minutes
            </span>
            <div class="blank_box"></div>
            <span class="meta">
              Words <span class="post-count">10.8k</span> In Total
            </span>
            <div class="blank_box"></div>
            <!-- WordCount end -->
            
            
            <!-- 不蒜子统计 start -->
            <span class="meta" id="busuanzi_container_page_pv">
              Viewed <span id="busuanzi_value_page_pv"><i class="fa fa-spinner fa-spin"></i></span> Times
            </span>
            <!-- 不蒜子统计 end -->
            


          </div>
          
        </div>
      </div>
    </div>
  </div>

  
  <!-- waveoverlay start -->
  <div class="preview-overlay">
    <svg class="preview-waves" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 24 150 28" preserveAspectRatio="none" shape-rendering="auto">
      <defs>
        <path id="gentle-wave" d="M-160 44c30 0 58-18 88-18s 58 18 88 18 58-18 88-18 58 18 88 18 v44h-352z"></path>
      </defs>
      <g class="preview-parallax">
        <use xlink:href="#gentle-wave" x="48" y="0" fill=var(--gentle-wave1)></use>
        <use xlink:href="#gentle-wave" x="48" y="3" fill=var(--gentle-wave2)></use>
        <use xlink:href="#gentle-wave" x="48" y="5" fill=var(--gentle-wave3)></use>
        <use xlink:href="#gentle-wave" x="48" y="7" fill=var(--gentle-wave)></use>
      </g>
    </svg>
  </div>
  <!-- waveoverlay end -->
  

</header>



		<!-- Main Content (Post contains
	Pager、
	tip、
	socialshare、
	gitalk、gitment、disqus-comment、
	Catalog、
	Sidebar、
	Featured-Tags、
	Friends Blog、
	anchorjs、
	) -->
		<!-- Modify by Yu-Hsuan Yen -->
<!-- Post Content -->
<article>
  <div class="container">
    <div class="row">
      <!-- Post Container -->
      <div class="col-lg-8 col-lg-offset-1 col-md-10 col-md-offset-1 post-container">

        <h1 id="类加载与字节码技术"><a href="#类加载与字节码技术" class="headerlink" title="类加载与字节码技术"></a>类加载与字节码技术</h1><h3 id="1-类文件结构"><a href="#1-类文件结构" class="headerlink" title="1. 类文件结构"></a>1. 类文件结构</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> cn.pzaily.concurrence;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@PackageName</span>: cn.pzaily.concurrence</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Description</span>:</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Author</span>: Pang</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Date</span>: 2021-10-27 11:21</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">HelloWorld</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;hello world&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>执行javac -parameters -d . HelloWorld.java</p>
<p>编译后</p>
<p><img src="image-20211027165533459.png" alt="image-20211027165533459"></p>
<p>根据JVM规范，类文件结构如下</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line">ClassFile &#123;</span><br><span class="line">    u4				magic;</span><br><span class="line">    u2				minor_version;</span><br><span class="line">    u2				major_version;</span><br><span class="line">    u2				constant_pool_count;</span><br><span class="line">    cp_info     	constant_pool[constant_pool_count-<span class="number">1</span>];</span><br><span class="line">    u2				access_flags;</span><br><span class="line">    u2				this_class;</span><br><span class="line">    u2				super_class;</span><br><span class="line">    u2				interfaces_count;</span><br><span class="line">    u2				interfaces[interfaces_count];</span><br><span class="line">    u2				fields_count;</span><br><span class="line">    file_info		fields[fields_count];</span><br><span class="line">    u2				methods_count;</span><br><span class="line">    method_info		methods[methods_count];</span><br><span class="line">    u2				attributes_count;</span><br><span class="line">    attribute_info	attributes[attributes_count];</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h4 id="1-1-魔数"><a href="#1-1-魔数" class="headerlink" title="1.1 魔数"></a>1.1 魔数</h4><p>0~3字节，表示它是否是class类型的文件</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Offset:   00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F </span><br><span class="line">00000000: CA FE BA BE 00 00 00 37 00 1F 0A 00 06 00 11 09</span><br></pre></td></tr></table></figure>
<h4 id="1-2-版本"><a href="#1-2-版本" class="headerlink" title="1.2 版本"></a>1.2 版本</h4><p>4~ 7字节，表示类的版本 </p>
<h4 id="1-3-常量池"><a href="#1-3-常量池" class="headerlink" title="1.3 常量池"></a>1.3 常量池</h4><p>8~ 9字节，表示常量池长度，00 1F表示常量池有#1~#30项，#0项不计入，也没有值</p>
<p>第#1项0A表示一个Method信息，00 06和00 11（17） 表示它引用了常量池中#6和#17项来获得这个方法的【所属类】和【方法名】</p>
<p>第#2项09表示一个Field信息，00 12（18）和00 13（19）表示它引用了常量池中#18和#19项来获得这个方法的【所属类】和【成员变量名】</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">00000000: CA FE BA BE 00 00 00 37 00 1F 0A 00 06 00 11 09  </span><br><span class="line">00000010: 00 12 00 13 08 00 14 0A 00 15 00 16 07 00 17 07</span><br></pre></td></tr></table></figure>
<p>第#3项08表示一个字符串常量名称，00 14（20）表示它引用常量池中#20项</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">00000010: 00 12 00 13 08 00 14 0A 00 15 00 16 07 00 17 07</span><br></pre></td></tr></table></figure>
<p>第#4项0A表示Method信息，00 15（21）和00 16（22）表示它引用常量池中#21项和#22项</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">00000010: 00 12 00 13 08 00 14 0A 00 15 00 16 07 00 17 07</span><br></pre></td></tr></table></figure>
<p>第#5项07表示一个Class信息，00 17（23）表示它引用常量池中#23项</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Offset:   00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F  </span><br><span class="line">00000010: 00 12 00 13 08 00 14 0A 00 15 00 16 07 00 17 07</span><br></pre></td></tr></table></figure>
<p>第#6项07表示一个Class信息，00 18（24）表示它引用常量池中#24项</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">00000010: 00 12 00 13 08 00 14 0A 00 15 00 16 07 00 17 07   </span><br><span class="line">00000020: 00 18 01 00 06 3C 69 6E 69 74 3E 01 00 03 28 29   </span><br></pre></td></tr></table></figure>
<p>第#7项01表示一个utf8串，00 06表示长度，3c 69 6e 69 74 3e是【<init>】</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">00000020: 00 18 01 00 06 3C 69 6E 69 74 3E 01 00 03 28 29</span><br></pre></td></tr></table></figure>
<p>第#8项01表示一个utf8串，00 03表示长度，28 29 56 是【()V】其实就是表示无参、无返回值</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">00000020: 00 18 01 00 06 3C 69 6E 69 74 3E 01 00 03 28 29   </span><br><span class="line">00000030: 56 01 00 04 43 6F 64 65 01 00 0F 4C 69 6E 65 4E</span><br></pre></td></tr></table></figure>
<p>第#9项01表示一个utf8串，00 04表示长度，43 6F 64 65 是【Code】</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">00000030: 56 01 00 04 43 6F 64 65 01 00 0F 4C 69 6E 65 4E</span><br></pre></td></tr></table></figure>
<p>第#10项01表示一个utf8串，00 0F（15）表示长度，4C 69 6E 65 4E   75 6D 62 65 72 54 61 62 6C 65是【LineNumberTable】</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">00000030: 56 01 00 04 43 6F 64 65 01 00 0F 4C 69 6E 65 4E</span><br><span class="line">00000040: 75 6D 62 65 72 54 61 62 6C 65 01 00 04 6D 61 69</span><br></pre></td></tr></table></figure>
<p>第#11项01表示一个utf8串，00 04表示长度，6d 61 69 6E是【main】</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">00000040: 75 6D 62 65 72 54 61 62 6C 65 01 00 04 6D 61 69</span><br><span class="line">00000050: 6E 01 00 16 28 5B 4C 6A 61 76 61 2F 6C 61 6E 67</span><br></pre></td></tr></table></figure>
<p>第#12项01表示一个utf8串，00 16（22）表示长度，28 5B 4C 6A 61 76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29 56是【(Ljava/lang/String;)V】</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">00000050: 6E 01 00 16 28 5B 4C 6A 61 76 61 2F 6C 61 6E 67   </span><br><span class="line">00000060: 2F 53 74 72 69 6E 67 3B 29 56 01 00 10 4D 65 74  </span><br></pre></td></tr></table></figure>
<p>第#13项01表示一个utf8串，00 10（16）表示长度，4D 65 74  68 6F 64 50 61 72 61 6D 65 74 65 72 73是【MethodParameters】</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">00000060: 2F 53 74 72 69 6E 67 3B 29 56 01 00 10 4D 65 74   </span><br><span class="line">00000070: 68 6F 64 50 61 72 61 6D 65 74 65 72 73 01 00 04   </span><br></pre></td></tr></table></figure>
<p>第#14项01表示一个utf8串，00 04表示长度，61 72 67 73是【args】</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">00000070: 68 6F 64 50 61 72 61 6D 65 74 65 72 73 01 00 04   </span><br><span class="line">00000080: 61 72 67 73 01 00 0A 53 6F 75 72 63 65 46 69 6C   </span><br></pre></td></tr></table></figure>
<p>第#15项01表示一个utf8串，00 0A（10）表示长度，53 6F 75 72 63 65 46 69 6C 65是【SourceFile】</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">00000080: 61 72 67 73 01 00 0A 53 6F 75 72 63 65 46 69 6C   </span><br><span class="line">00000090: 65 01 00 0F 48 65 6C 6C 6F 57 6F 72 6C 64 2E 6A   </span><br></pre></td></tr></table></figure>
<p>第#16项01表示一个utf8串，00 0F（15）表示长度，48 65 6C 6C 6F 57 6F 72 6C 64 2E 6A  61 76 61是【HelloWorld.java】</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">00000090: 65 01 00 0F 48 65 6C 6C 6F 57 6F 72 6C 64 2E 6A   </span><br><span class="line">000000a0: 61 76 61 0C 00 07 00 08 07 00 19 0C 00 1A 00 1B </span><br></pre></td></tr></table></figure>
<p>第#17项0c表示一个【名+类型】，00 07 与00 08引用常量池中#07,#08两项</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">000000a0: 61 76 61 0C 00 07 00 08 07 00 19 0C 00 1A 00 1B</span><br></pre></td></tr></table></figure>
<p>第#18项07表示一个Class信息，00 19（25）引用常量池中#25项</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">000000a0: 61 76 61 0C 00 07 00 08 07 00 19 0C 00 1A 00 1B</span><br></pre></td></tr></table></figure>
<p>第#19项0c表示一个【名+类型】，00 1A（26）与00 1B（27）引用常量池中#26，#27项</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">000000a0: 61 76 61 0C 00 07 00 08 07 00 19 0C 00 1A 00 1B</span><br></pre></td></tr></table></figure>
<p>第#20项01表示一个utf8串，00 0B（11）表示长度，68 65 6C 6C 6F 20 77 6F 72 6C 64是【hello world】</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">000000b0: 01 00 0B 68 65 6C 6C 6F 20 77 6F 72 6C 64 07 00</span><br></pre></td></tr></table></figure>
<p>第#21项07表示一个Class信息，00 1C（28）引用常量池中#28项</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">000000b0: 01 00 0B 68 65 6C 6C 6F 20 77 6F 72 6C 64 07 00   </span><br><span class="line">000000c0: 1C 0C 00 1D 00 1E 01 00 20 63 6E 2F 70 7A 61 69</span><br></pre></td></tr></table></figure>
<p>第#22项0c表示一个【名+类型】，00 1D（29） 与00 1E（30）引用常量池中#29、#30项</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">000000c0: 1C 0C 00 1D 00 1E 01 00 20 63 6E 2F 70 7A 61 69</span><br></pre></td></tr></table></figure>
<p>第#23项01表示一个utf8串，00 20（32）表示长度，63 6E 2F 70 7A 61 69  6C 79 2F 63 6F 6E 63 75 72 72 65 6E 63 65 2F 48  65 6C 6C 6F 57 6F 72 6C 64是【cn/pzaily/concurrence/HelloWorld】</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">000000c0: 1C 0C 00 1D 00 1E 01 00 20 63 6E 2F 70 7A 61 69   </span><br><span class="line">000000d0: 6C 79 2F 63 6F 6E 63 75 72 72 65 6E 63 65 2F 48   </span><br><span class="line">000000e0: 65 6C 6C 6F 57 6F 72 6C 64 01 00 10 6A 61 76 61   </span><br></pre></td></tr></table></figure>
<p>第#24项01表示一个utf8串，00 10（16）表示长度，6A 61 76 61 2F 6C 61 6E 67 2F 4F 62 6A 65 63 74是【java/lang/Object】</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">000000e0: 65 6C 6C 6F 57 6F 72 6C 64 01 00 10 6A 61 76 61   </span><br><span class="line">000000f0: 2F 6C 61 6E 67 2F 4F 62 6A 65 63 74 01 00 10 6A   </span><br></pre></td></tr></table></figure>
<p>第#25项01表示一个utf8串，00 10（16）表示长度，6A 61 76 61 2F 6C 61 6E 67 2F 53 79 73 74 65 6D是【java/lang/System】</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">000000f0: 2F 6C 61 6E 67 2F 4F 62 6A 65 63 74 01 00 10 6A   </span><br><span class="line">00000100: 61 76 61 2F 6C 61 6E 67 2F 53 79 73 74 65 6D 01   </span><br></pre></td></tr></table></figure>
<p>第#26项01表示一个utf8串，00 03表示长度，6F 75 74 是【out】</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">00000100: 61 76 61 2F 6C 61 6E 67 2F 53 79 73 74 65 6D 01   </span><br><span class="line">00000110: 00 03 6F 75 74 01 00 15 4C 6A 61 76 61 2F 69 6F   </span><br></pre></td></tr></table></figure>
<p>第#27项01表示一个utf8串，00 15（21）表示长度，4C 6A 61 76 61 2F 69 6F 2F 50 72 69 6E 74 53 74 72 65 61 6D 3B是【Ljava/io/PrintStream;】</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">00000110: 00 03 6F 75 74 01 00 15 4C 6A 61 76 61 2F 69 6F   </span><br><span class="line">00000120: 2F 50 72 69 6E 74 53 74 72 65 61 6D 3B 01 00 13   </span><br></pre></td></tr></table></figure>
<p>第#28项01表示一个utf8串，00 13（19）表示长度，6A 61 76 61 2F 69 6F 2F 50 72 69 6E 74 53 74 72  65 61 6D 是【java/io/PrintStream】</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">00000120: 2F 50 72 69 6E 74 53 74 72 65 61 6D 3B 01 00 13   </span><br><span class="line">00000130: 6A 61 76 61 2F 69 6F 2F 50 72 69 6E 74 53 74 72   </span><br><span class="line">00000140: 65 61 6D 01 00 07 70 72 69 6E 74 6C 6E 01 00 15   </span><br></pre></td></tr></table></figure>
<p>第#29项01表示i一个utf8串，00 07表示长度，70 72 69 6E 74 6C 6E是【println】</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">00000140: 65 61 6D 01 00 07 70 72 69 6E 74 6C 6E 01 00 15 </span><br></pre></td></tr></table></figure>
<p>第#30项01表示一个utf8串，00 15（21）表示长度，28 4C 6A 61 76 61 2F 6C 61 6E 67 2F 53 74 72 69  6E 67 3B 29 56是【(Ljava/lang/String;)V】</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">00000140: 65 61 6D 01 00 07 70 72 69 6E 74 6C 6E 01 00 15   </span><br><span class="line">00000150: 28 4C 6A 61 76 61 2F 6C 61 6E 67 2F 53 74 72 69   </span><br><span class="line">00000160: 6E 67 3B 29 56 00 21 00 05 00 06 00 00 00 00 00   </span><br></pre></td></tr></table></figure>
<h4 id="1-4-访问标识和继承信息"><a href="#1-4-访问标识和继承信息" class="headerlink" title="1.4 访问标识和继承信息"></a>1.4 访问标识和继承信息</h4><p><img src="image-20211027152541169.png" alt="image-20211027152541169"></p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">00000160: 6E 67 3B 29 56 00 21 00 05 00 06 00 00 00 00 00</span><br></pre></td></tr></table></figure>
<ul>
<li><p>00 21 表示该class是一个类，公共的</p>
</li>
<li><p>00 05 表示根据常量池中#5找到本类的全限定名</p>
</li>
<li><p>00 06表示根据常量池中#6找到父类的全限定名 </p>
</li>
<li><p>00 00表示接口数量，本类为0</p>
</li>
</ul>
<h4 id="1-5-Field信息"><a href="#1-5-Field信息" class="headerlink" title="1.5 Field信息"></a>1.5 Field信息</h4><p>表示成员变量数量，本类为0</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">00000160: 6E 67 3B 29 56 00 21 00 05 00 06 00 00 00 00 00</span><br></pre></td></tr></table></figure>
<p><img src="image-20211027153516999.png" alt="image-20211027153516999"></p>
<h4 id="1-6-Method信息"><a href="#1-6-Method信息" class="headerlink" title="1.6 Method信息"></a>1.6 Method信息</h4><p>00 02 表示方法数量，本类为2</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">00000160: 6E 67 3B 29 56 00 21 00 05 00 06 00 00 00 00 00   </span><br><span class="line">00000170: 02 00 01 00 07 00 08 00 01 00 09 00 00 00 1D 00   </span><br></pre></td></tr></table></figure>
<p>一个方法由访问修饰符，名称，参数描述，方法属性数量，方法属性组成</p>
<p><strong><em> method-init</em></strong></p>
<p><img src="image-20211027165355788.png" alt="image-20211027165355788"></p>
<p>00 01 代表访问修饰符（本类中是public）</p>
<p>00 07代表引用常量池#07项作为方法名称</p>
<p>00 08代表引用常量池#08项作为方法参数描述</p>
<p>00 01代表属性数量，本方法是1</p>
<p>方法属性：</p>
<ul>
<li>00 09表示引用常量池#09项，发现是【Code】属性</li>
<li>00 00 00 1D表示此属性的长度是29</li>
<li>00 01表示【操作数栈】最大深度</li>
<li>00 01表示【局部变量表】最大槽（slot）数</li>
<li>00 00 00 05表示字节码长度，本例是5</li>
<li>2A B7 00 01 B1是字节码指令</li>
<li>00 00 00 01表示方法细节属性数量，本例是2</li>
<li>00 0a表示引用常量池#10项，是【LineNumberTable】属性<ul>
<li>00 00 00 06表示此属性的总长度，本例是6</li>
<li>00 01表示【LineNumberTable】长度1</li>
<li>00 00表示【字节码】行号；00 09表示【java源码】行号</li>
</ul>
</li>
</ul>
<p><strong><em>method-main</em></strong></p>
<p><img src="image-20211027165502472.png" alt="image-20211027165502472"></p>
<p>00 09 代表方位修饰符（public static ）1 + 8</p>
<p>00 0B代表访问常量池#11 作为方法名称【main】</p>
<p>00 0c代表访问常量池#12作为方法参数描述【(Ljava/lang/String;)V】</p>
<p>00 02代表属性数量，本方法为2</p>
<p>方法属性：</p>
<ul>
<li>00 09表示引用常量池#09项，是【Code】属性</li>
<li>00 00 00 25表示此属性的长度是37</li>
<li>00 02表示【操作数栈】最大深度</li>
<li>00 01表示【局部变量表】最大槽（slot）数</li>
<li>00 00 00 09表示字节码长度为9</li>
<li>B2 00 02 12 03 B6 00 04 B1是字节码指令</li>
<li>00 00 00 01表示方法细节属性数量为2</li>
<li><p>00 0a表示引用常量池#10项，是【LineNumberTable】属性</p>
<ul>
<li>00 00 00 0a表示此属性的总长度为10</li>
<li>00 02表示【LineNumberTable】长度2</li>
<li>00 00表示【字节码】行号；00 0c表示【java源码】行号</li>
<li>00 08表示【字节码】行号；00 0d表示【java源码】行号</li>
</ul>
</li>
<li><p>00 0d表示引用常量池#13项，是【MethodParameters】属性</p>
<ul>
<li>00 00 00 05表示此属性的总长度为5</li>
<li>01 参数数量</li>
<li>00 0e表示引用常量池#14项，是【args】</li>
<li>00 00访问修饰符</li>
</ul>
</li>
</ul>
<h4 id="1-7-附加属性"><a href="#1-7-附加属性" class="headerlink" title="1.7 附加属性"></a>1.7 附加属性</h4><p><img src="image-20211027165052153.png" alt="image-20211027165052153"></p>
<ul>
<li>00 01表示附加属性数量</li>
<li>00 0F表示引用常量池#15，即【SourceFile】</li>
<li>00 00 00 02表示此属性的长度</li>
<li>00 10表示引用常量池#16，即【HelloWorld.java】</li>
</ul>
<h3 id="2-字节码指令"><a href="#2-字节码指令" class="headerlink" title="2. 字节码指令"></a>2. 字节码指令</h3><p>两组字节码指令</p>
<p>一个是method-init的字节码指令</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">2A B7 00 01 B1</span><br></pre></td></tr></table></figure>
<ol>
<li>2A   -&gt;   aload_0 加载slot0的局部变量，即this，做为下面的invokespecial构造方法调用的参数</li>
<li>B7   -&gt;    invokepecial 预备调用构造方法</li>
<li>00 01 引用常量池中#1项【java/lang/Object.<init>:()V】</li>
<li>B1 表示返回</li>
</ol>
<p>一个是method-main的字节码指令</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">B2 00 02 12 03 B6 00 04 B1</span><br></pre></td></tr></table></figure>
<ol>
<li>B2   -&gt;  getstatic 用来加载静态变量</li>
<li>00 02  引用常量池#2项，即【java/lang/System.out:Ljava/io/PrintStream;】</li>
<li>12    -&gt;    ldc 加载参数</li>
<li>03    引用常量池#3项，即【hello world】</li>
<li>B6   -&gt;  invokvirtual 预备调用成员方法</li>
<li>00 04 引用常量池中#4项，即【java/io/PrintStream.println:(Ljava/lang/String;)V】</li>
<li>B1 表示返回</li>
</ol>
<h4 id="javap工具"><a href="#javap工具" class="headerlink" title="javap工具"></a>javap工具</h4><p>javap -v HelloWorld.class</p>
<figure class="highlight lasso"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br></pre></td><td class="code"><pre><span class="line">Classfile /F:/ideaProject/practice/concurrence/<span class="literal">cn</span>/pzaily/concurrence/HelloWorld.class</span><br><span class="line">  Last modified <span class="number">2021</span>年<span class="number">10</span>月<span class="number">27</span>日; size <span class="number">484</span> <span class="built_in">bytes</span></span><br><span class="line">  MD5 checksum a514e89a58320b5030144f5e2e9a21e1</span><br><span class="line">  Compiled from <span class="string">&quot;HelloWorld.java&quot;</span></span><br><span class="line"><span class="keyword">public</span> class <span class="literal">cn</span>.pzaily.concurrence.HelloWorld</span><br><span class="line">  minor version: <span class="number">0</span></span><br><span class="line">  major version: <span class="number">55</span></span><br><span class="line">  flags: (<span class="number">0x0021</span>) ACC_PUBLIC, ACC_SUPER</span><br><span class="line">  this_class: #5                          <span class="comment">// cn/pzaily/concurrence/HelloWorld</span></span><br><span class="line">  super_class: #6                         <span class="comment">// java/lang/Object</span></span><br><span class="line">  interfaces: <span class="number">0</span>, fields: <span class="number">0</span>, methods: <span class="number">2</span>, attributes: <span class="number">1</span></span><br><span class="line">Constant pool:</span><br><span class="line">   #1 = Methodref          #6.#17         <span class="comment">// java/lang/Object.&quot;&lt;init&gt;&quot;:()V</span></span><br><span class="line">   #2 = Fieldref           #18.#19        <span class="comment">// java/lang/System.out:Ljava/io/PrintStream;</span></span><br><span class="line">   #3 = <span class="built_in">String</span>             #20            <span class="comment">// hello world</span></span><br><span class="line">   #4 = Methodref          #21.#22        <span class="comment">// java/io/PrintStream.println:(Ljava/lang/String;)V</span></span><br><span class="line">   #5 = Class              #23            <span class="comment">// cn/pzaily/concurrence/HelloWorld</span></span><br><span class="line">   #6 = Class              #24            <span class="comment">// java/lang/Object</span></span><br><span class="line">   #7 = Utf8               &lt;init&gt;</span><br><span class="line">   #8 = Utf8               ()V</span><br><span class="line">   #9 = Utf8               Code</span><br><span class="line">  #10 = Utf8               LineNumberTable</span><br><span class="line">  #11 = Utf8               main</span><br><span class="line">  #12 = Utf8               (<span class="meta">[</span>Ljava/lang/<span class="built_in">String</span>;)V</span><br><span class="line">  #13 = Utf8               MethodParameters</span><br><span class="line">  #14 = Utf8               args</span><br><span class="line">  #15 = Utf8               SourceFile</span><br><span class="line">  #16 = Utf8               HelloWorld.java</span><br><span class="line">  #17 = NameAndType        #7:#8          <span class="comment">// &quot;&lt;init&gt;&quot;:()V</span></span><br><span class="line">  #18 = Class              #25            <span class="comment">// java/lang/System</span></span><br><span class="line">  #19 = NameAndType        #26:#27        <span class="comment">// out:Ljava/io/PrintStream;</span></span><br><span class="line">  #20 = Utf8               hello world</span><br><span class="line">  #21 = Class              #28            <span class="comment">// java/io/PrintStream</span></span><br><span class="line">  #22 = NameAndType        #29:#30        <span class="comment">// println:(Ljava/lang/String;)V</span></span><br><span class="line">  #23 = Utf8               <span class="literal">cn</span>/pzaily/concurrence/HelloWorld</span><br><span class="line">  #24 = Utf8               java/lang/Object</span><br><span class="line">  #25 = Utf8               java/lang/System</span><br><span class="line">  #26 = Utf8               out</span><br><span class="line">  #27 = Utf8               Ljava/io/PrintStream;</span><br><span class="line">  #28 = Utf8               java/io/PrintStream</span><br><span class="line">  #29 = Utf8               println</span><br><span class="line">  #30 = Utf8               (Ljava/lang/<span class="built_in">String</span>;)V</span><br><span class="line">&#123;</span><br><span class="line">  <span class="keyword">public</span> <span class="literal">cn</span>.pzaily.concurrence.HelloWorld();</span><br><span class="line">    descriptor: ()V</span><br><span class="line">    flags: (<span class="number">0x0001</span>) ACC_PUBLIC</span><br><span class="line">    Code:</span><br><span class="line">      <span class="built_in">stack</span>=<span class="number">1</span>, locals=<span class="number">1</span>, args_size=<span class="number">1</span></span><br><span class="line">         <span class="number">0</span>: aload_0</span><br><span class="line">         <span class="number">1</span>: invokespecial #1                  <span class="comment">// Method java/lang/Object.&quot;&lt;init&gt;&quot;:()V</span></span><br><span class="line">         <span class="number">4</span>: <span class="keyword">return</span></span><br><span class="line">      LineNumberTable:</span><br><span class="line">        line <span class="number">9</span>: <span class="number">0</span></span><br><span class="line"></span><br><span class="line">  <span class="keyword">public</span> static <span class="literal">void</span> main(java.lang.<span class="built_in">String</span><span class="meta">[</span><span class="meta">]</span>);</span><br><span class="line">    descriptor: (<span class="meta">[</span>Ljava/lang/<span class="built_in">String</span>;)V</span><br><span class="line">    flags: (<span class="number">0x0009</span>) ACC_PUBLIC, ACC_STATIC</span><br><span class="line">    Code:</span><br><span class="line">      <span class="built_in">stack</span>=<span class="number">2</span>, locals=<span class="number">1</span>, args_size=<span class="number">1</span></span><br><span class="line">         <span class="number">0</span>: getstatic     #2                  <span class="comment">// Field java/lang/System.out:Ljava/io/PrintStream;</span></span><br><span class="line">         <span class="number">3</span>: ldc           #3                  <span class="comment">// String hello world</span></span><br><span class="line">         <span class="number">5</span>: invokevirtual #4                  <span class="comment">// Method java/io/PrintStream.println:(Ljava/lang/String;)V</span></span><br><span class="line">         <span class="number">8</span>: <span class="keyword">return</span></span><br><span class="line">      LineNumberTable:</span><br><span class="line">        line <span class="number">12</span>: <span class="number">0</span></span><br><span class="line">        line <span class="number">13</span>: <span class="number">8</span></span><br><span class="line">    MethodParameters:</span><br><span class="line">      Name                           Flags</span><br><span class="line">      args</span><br><span class="line">&#125;</span><br><span class="line">SourceFile: <span class="string">&quot;HelloWorld.java&quot;</span></span><br></pre></td></tr></table></figure>
<h4 id="方法执行流程"><a href="#方法执行流程" class="headerlink" title="方法执行流程"></a>方法执行流程</h4><h5 id="1-原始代码"><a href="#1-原始代码" class="headerlink" title="(1)  原始代码"></a>(1)  原始代码</h5><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> cn.pzaily.jvm;</span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Demo1</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> a = <span class="number">10</span>;</span><br><span class="line">        <span class="keyword">int</span> b = Short.MAX_VALUE + <span class="number">1</span>;</span><br><span class="line">        <span class="keyword">int</span> c = a + b;</span><br><span class="line">        System.out.println(c);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h5 id="2-编译后的字节码文件"><a href="#2-编译后的字节码文件" class="headerlink" title="(2). 编译后的字节码文件"></a>(2). 编译后的字节码文件</h5><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br></pre></td><td class="code"><pre><span class="line">F:\ideaProject\practice\jvm\target\classes\cn\pzaily\jvm&gt;javap -v Demo1.class</span><br><span class="line">Classfile /F:/ideaProject/practice/jvm/target/classes/cn/pzaily/jvm/Demo1.class</span><br><span class="line">  Last modified <span class="number">2021</span>年<span class="number">10</span>月<span class="number">28</span>日; size <span class="number">605</span> bytes</span><br><span class="line">  MD5 checksum e2a8574b4a93d257bc5d3f91eadcdfd0</span><br><span class="line">  Compiled from <span class="string">&quot;Demo1.java&quot;</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">cn</span>.<span class="title">pzaily</span>.<span class="title">jvm</span>.<span class="title">Demo1</span></span></span><br><span class="line">  minor version: 0</span><br><span class="line">  major version: <span class="number">52</span></span><br><span class="line">  flags: (<span class="number">0x0021</span>) ACC_PUBLIC, ACC_SUPER</span><br><span class="line">  this_class: #6                          // cn/pzaily/jvm/Demo1</span><br><span class="line">  super_class: #7                         // java/lang/Object</span><br><span class="line">  interfaces: <span class="number">0</span>, fields: <span class="number">0</span>, methods: <span class="number">2</span>, attributes: <span class="number">1</span></span><br><span class="line">Constant pool:</span><br><span class="line">   #1 = Methodref          #7.#25         // java/lang/Object.&quot;&lt;init&gt;&quot;:()V</span><br><span class="line">   #2 = Class              #26            // java/lang/Short</span><br><span class="line">   #3 = Integer            32768</span><br><span class="line">   #4 = Fieldref           #27.#28        // java/lang/System.out:Ljava/io/PrintStream;</span><br><span class="line">   #5 = Methodref          #29.#30        // java/io/PrintStream.println:(I)V</span><br><span class="line">   #6 = Class              #31            // cn/pzaily/jvm/Demo1</span><br><span class="line">   #7 = Class              #32            // java/lang/Object</span><br><span class="line">   #8 = Utf8               &lt;init&gt;</span><br><span class="line">   #9 = Utf8               ()V</span><br><span class="line">  #10 = Utf8               Code</span><br><span class="line">  #11 = Utf8               LineNumberTable</span><br><span class="line">  #12 = Utf8               LocalVariableTable</span><br><span class="line">  #13 = Utf8               this</span><br><span class="line">  #14 = Utf8               Lcn/pzaily/jvm/Demo1;</span><br><span class="line">  #15 = Utf8               main</span><br><span class="line">  #16 = Utf8               ([Ljava/lang/String;)V</span><br><span class="line">  #17 = Utf8               args</span><br><span class="line">  #18 = Utf8               [Ljava/lang/String;</span><br><span class="line">  #19 = Utf8               a</span><br><span class="line">  #20 = Utf8               I</span><br><span class="line">  #21 = Utf8               b</span><br><span class="line">  #22 = Utf8               c</span><br><span class="line">  #23 = Utf8               SourceFile</span><br><span class="line">  #24 = Utf8               Demo1.java</span><br><span class="line">  #25 = NameAndType        #8:#9          // &quot;&lt;init&gt;&quot;:()V</span><br><span class="line">  #26 = Utf8               java/lang/Short</span><br><span class="line">  #27 = Class              #33            // java/lang/System</span><br><span class="line">  #28 = NameAndType        #34:#35        // out:Ljava/io/PrintStream;</span><br><span class="line">  #29 = Class              #36            // java/io/PrintStream</span><br><span class="line">  #30 = NameAndType        #37:#38        // println:(I)V</span><br><span class="line">  #31 = Utf8               cn/pzaily/jvm/Demo1</span><br><span class="line">  #32 = Utf8               java/lang/Object</span><br><span class="line">  #33 = Utf8               java/lang/System</span><br><span class="line">  #34 = Utf8               out</span><br><span class="line">  #35 = Utf8               Ljava/io/PrintStream;</span><br><span class="line">  #36 = Utf8               java/io/PrintStream</span><br><span class="line">  #37 = Utf8               println</span><br><span class="line">  #38 = Utf8               (I)V</span><br><span class="line">&#123;</span><br><span class="line">  <span class="keyword">public</span> cn.pzaily.jvm.Demo1();</span><br><span class="line">    descriptor: ()V</span><br><span class="line">    flags: (<span class="number">0x0001</span>) ACC_PUBLIC</span><br><span class="line">    Code:</span><br><span class="line">      stack=<span class="number">1</span>, locals=<span class="number">1</span>, args_size=<span class="number">1</span></span><br><span class="line">         <span class="number">0</span>: aload_0</span><br><span class="line">         1: invokespecial #1                  // Method java/lang/Object.&quot;&lt;init&gt;&quot;:()V</span><br><span class="line">         <span class="number">4</span>: <span class="keyword">return</span></span><br><span class="line">      LineNumberTable:</span><br><span class="line">        line <span class="number">9</span>: <span class="number">0</span></span><br><span class="line">      LocalVariableTable:</span><br><span class="line">        Start  Length  Slot  Name   Signature</span><br><span class="line">            <span class="number">0</span>       <span class="number">5</span>     <span class="number">0</span>  <span class="keyword">this</span>   Lcn/pzaily/jvm/Demo1;</span><br><span class="line"></span><br><span class="line">  <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(java.lang.String[])</span></span>;</span><br><span class="line">    descriptor: ([Ljava/lang/String;)V</span><br><span class="line">    flags: (<span class="number">0x0009</span>) ACC_PUBLIC, ACC_STATIC</span><br><span class="line">    Code:</span><br><span class="line">      stack=<span class="number">2</span>, locals=<span class="number">4</span>, args_size=<span class="number">1</span></span><br><span class="line">         <span class="number">0</span>: bipush        <span class="number">10</span></span><br><span class="line">         <span class="number">2</span>: istore_1</span><br><span class="line">         3: ldc           #3                  // int 32768</span><br><span class="line">         <span class="number">5</span>: istore_2</span><br><span class="line">         <span class="number">6</span>: iload_1</span><br><span class="line">         <span class="number">7</span>: iload_2</span><br><span class="line">         <span class="number">8</span>: iadd</span><br><span class="line">         <span class="number">9</span>: istore_3</span><br><span class="line">        10: getstatic     #4                  // Field java/lang/System.out:Ljava/io/PrintStream;</span><br><span class="line">        <span class="number">13</span>: iload_3</span><br><span class="line">        14: invokevirtual #5                  // Method java/io/PrintStream.println:(I)V</span><br><span class="line">        <span class="number">17</span>: <span class="keyword">return</span></span><br><span class="line">      LineNumberTable:</span><br><span class="line">        line <span class="number">12</span>: <span class="number">0</span></span><br><span class="line">        line <span class="number">13</span>: <span class="number">3</span></span><br><span class="line">        line <span class="number">14</span>: <span class="number">6</span></span><br><span class="line">        line <span class="number">15</span>: <span class="number">10</span></span><br><span class="line">        line <span class="number">16</span>: <span class="number">17</span></span><br><span class="line">      LocalVariableTable:</span><br><span class="line">        Start  Length  Slot  Name   Signature</span><br><span class="line">            <span class="number">0</span>      <span class="number">18</span>     <span class="number">0</span>  args   [Ljava/lang/String;</span><br><span class="line">            <span class="number">3</span>      <span class="number">15</span>     <span class="number">1</span>     a   I</span><br><span class="line">            <span class="number">6</span>      <span class="number">12</span>     <span class="number">2</span>     b   I</span><br><span class="line">           <span class="number">10</span>       <span class="number">8</span>     <span class="number">3</span>     c   I</span><br><span class="line">&#125;</span><br><span class="line">SourceFile: <span class="string">&quot;Demo1.java&quot;</span></span><br><span class="line"></span><br></pre></td></tr></table></figure>
<h5 id="3-常量池载入运行时常量池"><a href="#3-常量池载入运行时常量池" class="headerlink" title="(3) 常量池载入运行时常量池"></a>(3) 常量池载入运行时常量池</h5><p>常量池处于方法区，此处为了便于显示，将其提出</p>
<p><img src="image-20211028165107513.png" alt="image-20211028165107513"></p>
<h5 id="4-方法字节码载入方法区"><a href="#4-方法字节码载入方法区" class="headerlink" title="(4) 方法字节码载入方法区"></a>(4) 方法字节码载入方法区</h5><p><img src="image-20211028165449276.png" alt="image-20211028165449276"></p>
<h5 id="5-main线程开始运行，分配栈帧内存"><a href="#5-main线程开始运行，分配栈帧内存" class="headerlink" title="(5) main线程开始运行，分配栈帧内存"></a>(5) main线程开始运行，分配栈帧内存</h5><p>（stack=2, locals=4）</p>
<p><img src="image-20211028165800373.png" alt="image-20211028165800373"></p>
<h5 id="6-执行引擎开始执行字节码"><a href="#6-执行引擎开始执行字节码" class="headerlink" title="(6) 执行引擎开始执行字节码"></a>(6) 执行引擎开始执行字节码</h5><h6 id="bipush-10"><a href="#bipush-10" class="headerlink" title="bipush 10"></a>bipush 10</h6><ul>
<li>将一个byte压入操作数栈（其长度会补齐4个字节）</li>
<li>sipush将一个short压入操作数栈（其长度会补齐4个字节）</li>
<li>ldc将一个int压入操作数栈</li>
<li>ldc2_w将一个long压入操作数栈（分两次压入，long是8个字节）</li>
<li>小的数字都是和字节码指令存在一起，超过short范围的数字存入常量池中</li>
</ul>
<p><img src="image-20211028170436313.png" alt="image-20211028170436313"></p>
<h6 id="istore-1"><a href="#istore-1" class="headerlink" title="istore_1"></a>istore_1</h6><ul>
<li>将操作数栈顶数据弹出，存入局部变量表的slot1</li>
</ul>
<p><img src="image-20211028170636494.png" alt="image-20211028170636494"></p>
<h6 id="ldc-3"><a href="#ldc-3" class="headerlink" title="ldc   #3"></a>ldc   #3</h6><ul>
<li>从常量池加载#3项数据到操作数栈</li>
<li>Short.MAX_VALUE是32767，32678=Short.MAX_VALUE+ 1是在编译期间计算的</li>
</ul>
<p><img src="image-20211028171134987.png" alt="image-20211028171134987"></p>
<h6 id="istore-2"><a href="#istore-2" class="headerlink" title="istore_2"></a>istore_2</h6><ul>
<li>将操作数栈顶数据弹出，存入局部变量表slot2中</li>
</ul>
<p><img src="image-20211028171328259.png" alt="image-20211028171328259"></p>
<h6 id="iload-1"><a href="#iload-1" class="headerlink" title="iload_1"></a>iload_1</h6><ul>
<li>将局部变量表中slot1的数据加载到操作数栈中</li>
</ul>
<p><img src="image-20211028171448440.png" alt="image-20211028171448440"></p>
<h6 id="iload-2"><a href="#iload-2" class="headerlink" title="iload_2"></a>iload_2</h6><ul>
<li>将局部变量表中slot2的数据加载到操作数栈中</li>
</ul>
<p><img src="image-20211028171525809.png" alt="image-20211028171525809"></p>
<h6 id="iadd"><a href="#iadd" class="headerlink" title="iadd"></a>iadd</h6><p><img src="image-20211028171602269.png" alt="image-20211028171602269"></p>
<h6 id="istore-3"><a href="#istore-3" class="headerlink" title="istore_3"></a>istore_3</h6><p><img src="image-20211028171644620.png" alt="image-20211028171644620"></p>
<h6 id="getstatic-4"><a href="#getstatic-4" class="headerlink" title="getstatic  #4"></a>getstatic  #4</h6><p><img src="image-20211028171842531.png" alt="image-20211028171842531"></p>
<p><img src="image-20211028171854262.png" alt="image-20211028171854262"></p>
<h6 id="iload-3"><a href="#iload-3" class="headerlink" title="iload_3"></a>iload_3</h6><p><img src="image-20211028171939187.png" alt="image-20211028171939187"></p>
<h6 id="invokevirtual-5"><a href="#invokevirtual-5" class="headerlink" title="invokevirtual #5"></a>invokevirtual #5</h6><ul>
<li>找到常量池#5项</li>
<li>定位到方法区<code>java/io/PrintStream.println:(I)V</code>方法</li>
<li>生成新的栈帧（分配locals、statck等）</li>
<li>传递参数，执行新栈帧中的字节码</li>
</ul>
<p><img src="image-20211028172416643.png" alt="image-20211028172416643"></p>
<ul>
<li>执行完毕，弹出栈帧</li>
<li>清除main操作数栈内容</li>
</ul>
<p><img src="image-20211028172457887.png" alt="image-20211028172457887"></p>
<h6 id="return"><a href="#return" class="headerlink" title="return"></a>return</h6><ul>
<li>完成main方法调用，弹出main栈帧</li>
<li>程序结束</li>
</ul>
<h4 id="分析i"><a href="#分析i" class="headerlink" title="分析i++"></a>分析i++</h4><h5 id="源程序"><a href="#源程序" class="headerlink" title="源程序"></a>源程序</h5><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> cn.pzaily.jvm;</span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Demo2</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> a = <span class="number">10</span>;</span><br><span class="line">        <span class="keyword">int</span> b = a++ + ++a + a--;</span><br><span class="line">        System.out.println(a);</span><br><span class="line">        System.out.println(b);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h5 id="字节码文件"><a href="#字节码文件" class="headerlink" title="字节码文件"></a>字节码文件</h5><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br></pre></td><td class="code"><pre><span class="line">F:\ideaProject\practice\jvm\target\classes\cn\pzaily\jvm&gt;javap -v Demo2.class</span><br><span class="line">Classfile /F:/ideaProject/practice/jvm/target/classes/cn/pzaily/jvm/Demo2.class</span><br><span class="line">  Last modified <span class="number">2021</span>年<span class="number">10</span>月<span class="number">28</span>日; size <span class="number">580</span> bytes</span><br><span class="line">  MD5 checksum a90e9c7067c1573290d5c3b8af741539</span><br><span class="line">  Compiled from <span class="string">&quot;Demo2.java&quot;</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">cn</span>.<span class="title">pzaily</span>.<span class="title">jvm</span>.<span class="title">Demo2</span></span></span><br><span class="line">  minor version: 0</span><br><span class="line">  major version: <span class="number">52</span></span><br><span class="line">  flags: (<span class="number">0x0021</span>) ACC_PUBLIC, ACC_SUPER</span><br><span class="line">  this_class: #4                          // cn/pzaily/jvm/Demo2</span><br><span class="line">  super_class: #5                         // java/lang/Object</span><br><span class="line">  interfaces: <span class="number">0</span>, fields: <span class="number">0</span>, methods: <span class="number">2</span>, attributes: <span class="number">1</span></span><br><span class="line">Constant pool:</span><br><span class="line">   #1 = Methodref          #5.#22         // java/lang/Object.&quot;&lt;init&gt;&quot;:()V</span><br><span class="line">   #2 = Fieldref           #23.#24        // java/lang/System.out:Ljava/io/PrintStream;</span><br><span class="line">   #3 = Methodref          #25.#26        // java/io/PrintStream.println:(I)V</span><br><span class="line">   #4 = Class              #27            // cn/pzaily/jvm/Demo2</span><br><span class="line">   #5 = Class              #28            // java/lang/Object</span><br><span class="line">   #6 = Utf8               &lt;init&gt;</span><br><span class="line">   #7 = Utf8               ()V</span><br><span class="line">   #8 = Utf8               Code</span><br><span class="line">   #9 = Utf8               LineNumberTable</span><br><span class="line">  #10 = Utf8               LocalVariableTable</span><br><span class="line">  #11 = Utf8               this</span><br><span class="line">  #12 = Utf8               Lcn/pzaily/jvm/Demo2;</span><br><span class="line">  #13 = Utf8               main</span><br><span class="line">  #14 = Utf8               ([Ljava/lang/String;)V</span><br><span class="line">  #15 = Utf8               args</span><br><span class="line">  #16 = Utf8               [Ljava/lang/String;</span><br><span class="line">  #17 = Utf8               a</span><br><span class="line">  #18 = Utf8               I</span><br><span class="line">  #19 = Utf8               b</span><br><span class="line">  #20 = Utf8               SourceFile</span><br><span class="line">  #21 = Utf8               Demo2.java</span><br><span class="line">  #22 = NameAndType        #6:#7          // &quot;&lt;init&gt;&quot;:()V</span><br><span class="line">  #23 = Class              #29            // java/lang/System</span><br><span class="line">  #24 = NameAndType        #30:#31        // out:Ljava/io/PrintStream;</span><br><span class="line">  #25 = Class              #32            // java/io/PrintStream</span><br><span class="line">  #26 = NameAndType        #33:#34        // println:(I)V</span><br><span class="line">  #27 = Utf8               cn/pzaily/jvm/Demo2</span><br><span class="line">  #28 = Utf8               java/lang/Object</span><br><span class="line">  #29 = Utf8               java/lang/System</span><br><span class="line">  #30 = Utf8               out</span><br><span class="line">  #31 = Utf8               Ljava/io/PrintStream;</span><br><span class="line">  #32 = Utf8               java/io/PrintStream</span><br><span class="line">  #33 = Utf8               println</span><br><span class="line">  #34 = Utf8               (I)V</span><br><span class="line">&#123;</span><br><span class="line">  <span class="keyword">public</span> cn.pzaily.jvm.Demo2();</span><br><span class="line">    descriptor: ()V</span><br><span class="line">    flags: (<span class="number">0x0001</span>) ACC_PUBLIC</span><br><span class="line">    Code:</span><br><span class="line">      stack=<span class="number">1</span>, locals=<span class="number">1</span>, args_size=<span class="number">1</span></span><br><span class="line">         <span class="number">0</span>: aload_0</span><br><span class="line">         1: invokespecial #1                  // Method java/lang/Object.&quot;&lt;init&gt;&quot;:()V</span><br><span class="line">         <span class="number">4</span>: <span class="keyword">return</span></span><br><span class="line">      LineNumberTable:</span><br><span class="line">        line <span class="number">9</span>: <span class="number">0</span></span><br><span class="line">      LocalVariableTable:</span><br><span class="line">        Start  Length  Slot  Name   Signature</span><br><span class="line">            <span class="number">0</span>       <span class="number">5</span>     <span class="number">0</span>  <span class="keyword">this</span>   Lcn/pzaily/jvm/Demo2;</span><br><span class="line"></span><br><span class="line">  <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(java.lang.String[])</span></span>;</span><br><span class="line">    descriptor: ([Ljava/lang/String;)V</span><br><span class="line">    flags: (<span class="number">0x0009</span>) ACC_PUBLIC, ACC_STATIC</span><br><span class="line">    Code:</span><br><span class="line">      stack=<span class="number">2</span>, locals=<span class="number">3</span>, args_size=<span class="number">1</span></span><br><span class="line">         <span class="number">0</span>: bipush        <span class="number">10</span></span><br><span class="line">         <span class="number">2</span>: istore_1</span><br><span class="line">         <span class="number">3</span>: iload_1</span><br><span class="line">         <span class="number">4</span>: iinc          <span class="number">1</span>, <span class="number">1</span></span><br><span class="line">         <span class="number">7</span>: iinc          <span class="number">1</span>, <span class="number">1</span></span><br><span class="line">        <span class="number">10</span>: iload_1</span><br><span class="line">        <span class="number">11</span>: iadd</span><br><span class="line">        <span class="number">12</span>: iload_1</span><br><span class="line">        <span class="number">13</span>: iinc          <span class="number">1</span>, -<span class="number">1</span></span><br><span class="line">        <span class="number">16</span>: iadd</span><br><span class="line">        <span class="number">17</span>: istore_2</span><br><span class="line">        18: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;</span><br><span class="line">        <span class="number">21</span>: iload_1</span><br><span class="line">        22: invokevirtual #3                  // Method java/io/PrintStream.println:(I)V</span><br><span class="line">        25: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;</span><br><span class="line">        <span class="number">28</span>: iload_2</span><br><span class="line">        29: invokevirtual #3                  // Method java/io/PrintStream.println:(I)V</span><br><span class="line">        <span class="number">32</span>: <span class="keyword">return</span></span><br><span class="line">      LineNumberTable:</span><br><span class="line">        line <span class="number">11</span>: <span class="number">0</span></span><br><span class="line">        line <span class="number">12</span>: <span class="number">3</span></span><br><span class="line">        line <span class="number">13</span>: <span class="number">18</span></span><br><span class="line">        line <span class="number">14</span>: <span class="number">25</span></span><br><span class="line">        line <span class="number">15</span>: <span class="number">32</span></span><br><span class="line">      LocalVariableTable:</span><br><span class="line">        Start  Length  Slot  Name   Signature</span><br><span class="line">            <span class="number">0</span>      <span class="number">33</span>     <span class="number">0</span>  args   [Ljava/lang/String;</span><br><span class="line">            <span class="number">3</span>      <span class="number">30</span>     <span class="number">1</span>     a   I</span><br><span class="line">           <span class="number">18</span>      <span class="number">15</span>     <span class="number">2</span>     b   I</span><br><span class="line">&#125;</span><br><span class="line">SourceFile: <span class="string">&quot;Demo2.java&quot;</span></span><br></pre></td></tr></table></figure>
<h5 id="分析"><a href="#分析" class="headerlink" title="分析"></a>分析</h5><ul>
<li><code>iinc</code>指令是直接在局部变量slot上进行运算</li>
<li>a++与++a的区别是限制iload还是先执行iinc</li>
</ul>
<p><img src="image-20211028174219120.png" alt="image-20211028174219120"></p>
<p><img src="image-20211028174234431.png" alt="image-20211028174234431"></p>
<p><img src="image-20211028174306473.png" alt="image-20211028174306473"></p>
<p><img src="image-20211028174320276.png" alt="image-20211028174320276"></p>
<p><img src="image-20211028174338077.png" alt="image-20211028174338077"></p>
<p><img src="image-20211028174402666.png" alt="image-20211028174402666"></p>
<h4 id="条件判断指令"><a href="#条件判断指令" class="headerlink" title="条件判断指令"></a>条件判断指令</h4><p><img src="image-20211028174654950.png" alt="image-20211028174654950"></p>
<ul>
<li>byte、short、char都按int比较，操作数栈都是4字节</li>
<li>goto用来进行跳转到指定行号的字节码</li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Demo3</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> a = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">if</span> (a == <span class="number">0</span>) &#123;</span><br><span class="line">            a = <span class="number">10</span>;</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            a = <span class="number">20</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="number">0</span>: iconst_0</span><br><span class="line">      <span class="number">1</span>: istore_1</span><br><span class="line">      <span class="number">2</span>: iload_1</span><br><span class="line">      <span class="number">3</span>: ifne          <span class="number">12</span></span><br><span class="line">      <span class="number">6</span>: bipush        <span class="number">10</span></span><br><span class="line">      <span class="number">8</span>: istore_1</span><br><span class="line">      <span class="number">9</span>: goto          <span class="number">15</span></span><br><span class="line">     <span class="number">12</span>: bipush        <span class="number">20</span></span><br><span class="line">     <span class="number">14</span>: istore_1</span><br><span class="line">     <span class="number">15</span>: <span class="keyword">return</span></span><br><span class="line"></span><br></pre></td></tr></table></figure>
<h4 id="循环控制指令"><a href="#循环控制指令" class="headerlink" title="循环控制指令"></a>循环控制指令</h4><p>循环控制还是条件判断语句</p>
<ul>
<li>while循环</li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Demo4</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> a = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">while</span> (a &lt; <span class="number">10</span>) &#123;</span><br><span class="line">            a++;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"> <span class="number">0</span>: iconst_0</span><br><span class="line"> <span class="number">1</span>: istore_1</span><br><span class="line"> <span class="number">2</span>: iload_1</span><br><span class="line"> <span class="number">3</span>: bipush        <span class="number">10</span></span><br><span class="line"> <span class="number">5</span>: if_icmpge     <span class="number">14</span></span><br><span class="line"> <span class="number">8</span>: iinc          <span class="number">1</span>, <span class="number">1</span></span><br><span class="line"><span class="number">11</span>: goto          <span class="number">2</span></span><br><span class="line"><span class="number">14</span>: <span class="keyword">return</span></span><br><span class="line"></span><br></pre></td></tr></table></figure>
<ul>
<li>do while循环</li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Demo5</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> a = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">do</span> &#123;</span><br><span class="line">            a++;</span><br><span class="line">        &#125; <span class="keyword">while</span>(a &lt; <span class="number">10</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"> <span class="number">0</span>: iconst_0</span><br><span class="line"> <span class="number">1</span>: istore_1</span><br><span class="line"> <span class="number">2</span>: iinc          <span class="number">1</span>, <span class="number">1</span></span><br><span class="line"> <span class="number">5</span>: iload_1</span><br><span class="line"> <span class="number">6</span>: bipush        <span class="number">10</span></span><br><span class="line"> <span class="number">8</span>: if_icmplt     <span class="number">2</span></span><br><span class="line"><span class="number">11</span>: <span class="keyword">return</span></span><br></pre></td></tr></table></figure>
<ul>
<li>for 循环</li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Demo6</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; <span class="number">10</span>; i++) &#123;</span><br><span class="line"></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"> <span class="number">0</span>: iconst_0</span><br><span class="line"> <span class="number">1</span>: istore_1</span><br><span class="line"> <span class="number">2</span>: iload_1</span><br><span class="line"> <span class="number">3</span>: bipush        <span class="number">10</span></span><br><span class="line"> <span class="number">5</span>: if_icmpge     <span class="number">14</span></span><br><span class="line"> <span class="number">8</span>: iinc          <span class="number">1</span>, <span class="number">1</span></span><br><span class="line"><span class="number">11</span>: goto          <span class="number">2</span></span><br><span class="line"><span class="number">14</span>: <span class="keyword">return</span></span><br></pre></td></tr></table></figure>
<blockquote>
<p>while和fro字节码一样</p>
</blockquote>
<h4 id="构造方法"><a href="#构造方法" class="headerlink" title="构造方法"></a>构造方法</h4><h5 id="（1）-lt-cinit-gt-V"><a href="#（1）-lt-cinit-gt-V" class="headerlink" title="（1）&lt;cinit&gt;()V"></a>（1）<code>&lt;cinit&gt;()V</code></h5><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Demo8</span> </span>&#123;</span><br><span class="line">    <span class="keyword">static</span> &#123;</span><br><span class="line">        i = <span class="number">40</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">static</span> &#123;</span><br><span class="line">        i = <span class="number">20</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">static</span> <span class="keyword">int</span> i = <span class="number">10</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>编译器会按从上至下的顺序，将所有static静态代码块和静态成员变量赋值的代码，合并为一个特殊的方法<code>&lt;cinit&gt;()V</code></p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"> <span class="number">0</span>: bipush        <span class="number">40</span></span><br><span class="line"> 2: putstatic     #2                  // Field i:I</span><br><span class="line"> <span class="number">5</span>: bipush        <span class="number">20</span></span><br><span class="line"> 7: putstatic     #2                  // Field i:I</span><br><span class="line"><span class="number">10</span>: bipush        <span class="number">10</span></span><br><span class="line">12: putstatic     #2                  // Field i:I</span><br><span class="line"><span class="number">15</span>: <span class="keyword">return</span></span><br><span class="line"></span><br></pre></td></tr></table></figure>
<p><code>&lt;cinit&gt;()V</code>方法会在类加载的初始化阶段被调用</p>
<h5 id="（2）-lt-init-gt-V"><a href="#（2）-lt-init-gt-V" class="headerlink" title="（2）&lt;init&gt;()V"></a>（2）<code>&lt;init&gt;()V</code></h5><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Demo9</span> </span>&#123;</span><br><span class="line">    <span class="keyword">private</span> String a = <span class="string">&quot;string&quot;</span>;</span><br><span class="line"></span><br><span class="line">    &#123;</span><br><span class="line">        b = <span class="number">20</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">int</span> b = <span class="number">10</span>;</span><br><span class="line"></span><br><span class="line">    &#123;</span><br><span class="line">        a = <span class="string">&quot;string2&quot;</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">Demo9</span><span class="params">(String a, <span class="keyword">int</span> b)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.a = a;</span><br><span class="line">        <span class="keyword">this</span>.b = b;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        Demo9 demo9 = <span class="keyword">new</span> Demo9(<span class="string">&quot;string3&quot;</span>, <span class="number">30</span>);</span><br><span class="line">        System.out.println(demo9.a);</span><br><span class="line">        System.out.println(demo9.b);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>编译器会按从上至下的顺序，收集所有{}代码块和成员变量赋值的代码，形成新的构造方法，单原始构造方法内的代码总是在最后。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> cn.pzaily.jvm.Demo9(java.lang.String, <span class="keyword">int</span>);</span><br><span class="line">    descriptor: (Ljava/lang/String;I)V</span><br><span class="line">    flags: (<span class="number">0x0001</span>) ACC_PUBLIC</span><br><span class="line">    Code:</span><br><span class="line">      stack=<span class="number">2</span>, locals=<span class="number">3</span>, args_size=<span class="number">3</span></span><br><span class="line">         <span class="number">0</span>: aload_0</span><br><span class="line">         1: invokespecial #1                  // Method java/lang/Object.&quot;&lt;init&gt;&quot;:()V</span><br><span class="line">         <span class="number">4</span>: aload_0</span><br><span class="line">         5: ldc           #2                  // String string</span><br><span class="line">         7: putfield      #3                  // Field a:Ljava/lang/String;</span><br><span class="line">        <span class="number">10</span>: aload_0</span><br><span class="line">        <span class="number">11</span>: bipush        <span class="number">20</span></span><br><span class="line">        13: putfield      #4                  // Field b:I</span><br><span class="line">        <span class="number">16</span>: aload_0</span><br><span class="line">        <span class="number">17</span>: bipush        <span class="number">10</span></span><br><span class="line">        19: putfield      #4                  // Field b:I</span><br><span class="line">        <span class="number">22</span>: aload_0</span><br><span class="line">        23: ldc           #5                  // String string2</span><br><span class="line">        25: putfield      #3                  // Field a:Ljava/lang/String;</span><br><span class="line">        <span class="number">28</span>: aload_0</span><br><span class="line">        <span class="number">29</span>: aload_1</span><br><span class="line">        30: putfield      #3                  // Field a:Ljava/lang/String;</span><br><span class="line">        <span class="number">33</span>: aload_0</span><br><span class="line">        <span class="number">34</span>: iload_2</span><br><span class="line">        35: putfield      #4                  // Field b:I</span><br><span class="line">        <span class="number">38</span>: <span class="keyword">return</span></span><br><span class="line">      LineNumberTable:</span><br><span class="line">        line <span class="number">21</span>: <span class="number">0</span></span><br><span class="line">        line <span class="number">10</span>: <span class="number">4</span></span><br><span class="line">        line <span class="number">13</span>: <span class="number">10</span></span><br><span class="line">        line <span class="number">15</span>: <span class="number">16</span></span><br><span class="line">        line <span class="number">18</span>: <span class="number">22</span></span><br><span class="line">        line <span class="number">22</span>: <span class="number">28</span></span><br><span class="line">        line <span class="number">23</span>: <span class="number">33</span></span><br><span class="line">        line <span class="number">24</span>: <span class="number">38</span></span><br><span class="line">      LocalVariableTable:</span><br><span class="line">        Start  Length  Slot  Name   Signature</span><br><span class="line">            <span class="number">0</span>      <span class="number">39</span>     <span class="number">0</span>  <span class="keyword">this</span>   Lcn/pzaily/jvm/Demo9;</span><br><span class="line">            <span class="number">0</span>      <span class="number">39</span>     <span class="number">1</span>     a   Ljava/lang/String;</span><br><span class="line">            <span class="number">0</span>      <span class="number">39</span>     <span class="number">2</span>     b   I</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<h4 id="方法调用"><a href="#方法调用" class="headerlink" title="方法调用"></a>方法调用</h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Demo10</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">Demo10</span><span class="params">()</span> </span>&#123;&#125;</span><br><span class="line">    <span class="function"><span class="keyword">private</span> <span class="keyword">void</span> <span class="title">method1</span><span class="params">()</span> </span>&#123;&#125;</span><br><span class="line">    <span class="function"><span class="keyword">private</span> <span class="keyword">final</span> <span class="keyword">void</span> <span class="title">method2</span><span class="params">()</span> </span>&#123;&#125;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">method3</span><span class="params">()</span> </span>&#123;&#125;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">method4</span><span class="params">()</span> </span>&#123;&#125;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        Demo10 demo10 = <span class="keyword">new</span> Demo10();</span><br><span class="line">        demo10.method1();</span><br><span class="line">        demo10.method2();</span><br><span class="line">        demo10.method3();</span><br><span class="line">        demo10.method4();</span><br><span class="line">        Demo10.method4();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"> 0: new           #2                  // class cn/pzaily/jvm/Demo10</span><br><span class="line"> <span class="number">3</span>: dup</span><br><span class="line"> 4: invokespecial #3                  // Method &quot;&lt;init&gt;&quot;:()V</span><br><span class="line"> <span class="number">7</span>: astore_1</span><br><span class="line"> <span class="number">8</span>: aload_1</span><br><span class="line"> 9: invokespecial #4                  // Method method1:()V</span><br><span class="line"><span class="number">12</span>: aload_1</span><br><span class="line">13: invokespecial #5                  // Method method2:()V</span><br><span class="line"><span class="number">16</span>: aload_1</span><br><span class="line">17: invokevirtual #6                  // Method method3:()V</span><br><span class="line"><span class="number">20</span>: aload_1</span><br><span class="line"><span class="number">21</span>: pop</span><br><span class="line">22: invokestatic  #7                  // Method method4:()V</span><br><span class="line">25: invokestatic  #7                  // Method method4:()V</span><br><span class="line"><span class="number">28</span>: <span class="keyword">return</span></span><br></pre></td></tr></table></figure>
<ul>
<li>new 是创建【对象】，给对象分配堆内存，执行成功会将【对象引用】压入操作数栈</li>
<li>dup是复制操作数栈栈顶的内容，即【对象引用】，为什么需要引用呢，一个是要配合invokespecial调用该对象的构造方法<code>&quot;&lt;init&gt;&quot;:()V</code> 消耗掉栈顶一个引用，另一个是配合astore_1赋值给局部变量</li>
<li>最终方法（fianl）、私有方法（private）、构造方法都是由invokespecial指令来调用，属性静态绑定</li>
<li>普通成员方法是由invokevirtual调用，属于动态绑定，即支持多态</li>
<li>成员方法与静态方法调用的另一个区别是，执行方法前是否需要【对象引用】</li>
<li><code>d.method4();</code>是通过【对象引用】调用一个静态方法，可以看到在调用invokestatic之前执行了pop指令，把【对象引用】从操作数栈弹调了，因此，不应该通过类实例访问静态成员。</li>
<li>还有一个执行invokespecial的情况是通过super调用父类方法</li>
</ul>
<h4 id="多态的原理"><a href="#多态的原理" class="headerlink" title="多态的原理"></a>多态的原理</h4><p>当执行invokevirtual指令时，</p>
<ol>
<li>先通过栈帧中的对象引用找到对象</li>
<li>分析对象头，找到对象的实际Class</li>
<li>Class结构中有vtable，它在类加载的链接阶段就已经根据方法的重写规则生成号了</li>
<li>查表得到方法得具体地址</li>
<li>执行方法得字节码</li>
</ol>
<h4 id="异常处理"><a href="#异常处理" class="headerlink" title="异常处理"></a>异常处理</h4><h5 id="try-catch"><a href="#try-catch" class="headerlink" title="try-catch"></a>try-catch</h5><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Demo11</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> i = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            i = <span class="number">10</span>;</span><br><span class="line">        &#125; <span class="keyword">catch</span> (Exception e) &#123;</span><br><span class="line">            i = <span class="number">20</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(java.lang.String[])</span></span>;</span><br><span class="line">   descriptor: ([Ljava/lang/String;)V</span><br><span class="line">   flags: (<span class="number">0x0009</span>) ACC_PUBLIC, ACC_STATIC</span><br><span class="line">   Code:</span><br><span class="line">     stack=<span class="number">1</span>, locals=<span class="number">3</span>, args_size=<span class="number">1</span></span><br><span class="line">        <span class="number">0</span>: iconst_0</span><br><span class="line">        <span class="number">1</span>: istore_1</span><br><span class="line">        <span class="number">2</span>: bipush        <span class="number">10</span></span><br><span class="line">        <span class="number">4</span>: istore_1</span><br><span class="line">        <span class="number">5</span>: goto          <span class="number">12</span></span><br><span class="line">        <span class="number">8</span>: astore_2</span><br><span class="line">        <span class="number">9</span>: bipush        <span class="number">20</span></span><br><span class="line">       <span class="number">11</span>: istore_1</span><br><span class="line">       <span class="number">12</span>: <span class="keyword">return</span></span><br><span class="line">     Exception table:</span><br><span class="line">        from    to  target type</span><br><span class="line">            <span class="number">2</span>     <span class="number">5</span>     <span class="number">8</span>   Class java/lang/Exception</span><br><span class="line">     LineNumberTable: ...</span><br><span class="line">     LocalVariableTable:</span><br><span class="line">       Start  Length  Slot  Name   Signature</span><br><span class="line">           <span class="number">9</span>       <span class="number">3</span>     <span class="number">2</span>     e   Ljava/lang/Exception;</span><br><span class="line">           <span class="number">0</span>      <span class="number">13</span>     <span class="number">0</span>  args   [Ljava/lang/String;</span><br><span class="line">           <span class="number">2</span>      <span class="number">11</span>     <span class="number">1</span>     i   I</span><br><span class="line">     StackMapTable: ...</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<ul>
<li>多出一个Exception table的结构，[from, to)是前闭后开的检测范围，一旦这个范围内的字节码执行出现异常，则通过type匹配异常类型，如果一致，进入target所指示行号。</li>
<li>8行的字节码执行astore_2是将异常对象引用存入局部变量表的slot2位置</li>
</ul>
<h5 id="多个single-catch块的情况"><a href="#多个single-catch块的情况" class="headerlink" title="多个single-catch块的情况"></a>多个single-catch块的情况</h5><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Demo12</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> i = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            i = <span class="number">10</span>;</span><br><span class="line">        &#125; <span class="keyword">catch</span> (ArithmeticException e) &#123;</span><br><span class="line">            i = <span class="number">20</span>;</span><br><span class="line">        &#125; <span class="keyword">catch</span> (NullPointerException e) &#123;</span><br><span class="line">            i = <span class="number">30</span>;</span><br><span class="line">        &#125; <span class="keyword">catch</span> (Exception e) &#123;</span><br><span class="line">            i = <span class="number">40</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(java.lang.String[])</span></span>;</span><br><span class="line">    descriptor: ([Ljava/lang/String;)V</span><br><span class="line">    flags: (<span class="number">0x0009</span>) ACC_PUBLIC, ACC_STATIC</span><br><span class="line">    Code:</span><br><span class="line">      stack=<span class="number">1</span>, locals=<span class="number">3</span>, args_size=<span class="number">1</span></span><br><span class="line">         <span class="number">0</span>: iconst_0</span><br><span class="line">         <span class="number">1</span>: istore_1</span><br><span class="line">         <span class="number">2</span>: bipush        <span class="number">10</span></span><br><span class="line">         <span class="number">4</span>: istore_1</span><br><span class="line">         <span class="number">5</span>: goto          <span class="number">26</span></span><br><span class="line">         <span class="number">8</span>: astore_2</span><br><span class="line">         <span class="number">9</span>: bipush        <span class="number">20</span></span><br><span class="line">        <span class="number">11</span>: istore_1</span><br><span class="line">        <span class="number">12</span>: goto          <span class="number">26</span></span><br><span class="line">        <span class="number">15</span>: astore_2</span><br><span class="line">        <span class="number">16</span>: bipush        <span class="number">30</span></span><br><span class="line">        <span class="number">18</span>: istore_1</span><br><span class="line">        <span class="number">19</span>: goto          <span class="number">26</span></span><br><span class="line">        <span class="number">22</span>: astore_2</span><br><span class="line">        <span class="number">23</span>: bipush        <span class="number">40</span></span><br><span class="line">        <span class="number">25</span>: istore_1</span><br><span class="line">        <span class="number">26</span>: <span class="keyword">return</span></span><br><span class="line">      Exception table:</span><br><span class="line">         from    to  target type</span><br><span class="line">             <span class="number">2</span>     <span class="number">5</span>     <span class="number">8</span>   Class java/lang/ArithmeticException</span><br><span class="line">             <span class="number">2</span>     <span class="number">5</span>    <span class="number">15</span>   Class java/lang/NullPointerException</span><br><span class="line">             <span class="number">2</span>     <span class="number">5</span>    <span class="number">22</span>   Class java/lang/Exception</span><br><span class="line">      LineNumberTable: ...</span><br><span class="line">      LocalVariableTable:</span><br><span class="line">        Start  Length  Slot  Name   Signature</span><br><span class="line">            <span class="number">9</span>       <span class="number">3</span>     <span class="number">2</span>     e   Ljava/lang/ArithmeticException;</span><br><span class="line">           <span class="number">16</span>       <span class="number">3</span>     <span class="number">2</span>     e   Ljava/lang/NullPointerException;</span><br><span class="line">           <span class="number">23</span>       <span class="number">3</span>     <span class="number">2</span>     e   Ljava/lang/Exception;</span><br><span class="line">            <span class="number">0</span>      <span class="number">27</span>     <span class="number">0</span>  args   [Ljava/lang/String;</span><br><span class="line">            <span class="number">2</span>      <span class="number">25</span>     <span class="number">1</span>     i   I</span><br><span class="line">      StackMapTable: ....</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<ul>
<li>因为异常出现时，只能进入Exception table中一个分支，所有局部变量表slot2位置被共用。</li>
</ul>
<h5 id="multi-catch的情况"><a href="#multi-catch的情况" class="headerlink" title="multi-catch的情况"></a>multi-catch的情况</h5><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Demo13</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">method</span><span class="params">()</span></span>&#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;hello world&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> i = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            Method method = Demo13.class.getMethod(<span class="string">&quot;method&quot;</span>);</span><br><span class="line">            method.invoke(<span class="keyword">null</span>);</span><br><span class="line">        &#125; <span class="keyword">catch</span> (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) &#123;</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(java.lang.String[])</span></span>;</span><br><span class="line">    descriptor: ([Ljava/lang/String;)V</span><br><span class="line">    flags: (<span class="number">0x0009</span>) ACC_PUBLIC, ACC_STATIC</span><br><span class="line">    Code:</span><br><span class="line">      stack=<span class="number">3</span>, locals=<span class="number">3</span>, args_size=<span class="number">1</span></span><br><span class="line">         <span class="number">0</span>: iconst_0</span><br><span class="line">         <span class="number">1</span>: istore_1</span><br><span class="line">         2: ldc           #5                  // class cn/pzaily/jvm/Demo13</span><br><span class="line">         4: ldc           #6                  // String method</span><br><span class="line">         <span class="number">6</span>: iconst_0</span><br><span class="line">         7: anewarray     #7                  // class java/lang/Class</span><br><span class="line">        10: invokevirtual #8                  // Method java/lang/Class.getMethod:(Ljava/lang/String;[Ljava/lang/C</span><br><span class="line">lass;)Ljava/lang/reflect/Method;</span><br><span class="line">        <span class="number">13</span>: astore_2</span><br><span class="line">        <span class="number">14</span>: aload_2</span><br><span class="line">        <span class="number">15</span>: aconst_null</span><br><span class="line">        <span class="number">16</span>: iconst_0</span><br><span class="line">        17: anewarray     #9                  // class java/lang/Object</span><br><span class="line">        20: invokevirtual #10                 // Method java/lang/reflect/Method.invoke:(Ljava/lang/Object;[Ljava/</span><br><span class="line">lang/Object;)Ljava/lang/Object;</span><br><span class="line">        <span class="number">23</span>: pop</span><br><span class="line">        <span class="number">24</span>: goto          <span class="number">32</span></span><br><span class="line">        <span class="number">27</span>: astore_2</span><br><span class="line">        <span class="number">28</span>: aload_2</span><br><span class="line">        29: invokevirtual #14                 // Method java/lang/ReflectiveOperationException.printStackTrace:()V</span><br><span class="line"></span><br><span class="line">        <span class="number">32</span>: <span class="keyword">return</span></span><br><span class="line">      Exception table:</span><br><span class="line">         from    to  target type</span><br><span class="line">             <span class="number">2</span>    <span class="number">24</span>    <span class="number">27</span>   Class java/lang/NoSuchMethodException</span><br><span class="line">             <span class="number">2</span>    <span class="number">24</span>    <span class="number">27</span>   Class java/lang/IllegalAccessException</span><br><span class="line">             <span class="number">2</span>    <span class="number">24</span>    <span class="number">27</span>   Class java/lang/reflect/InvocationTargetException</span><br><span class="line">      LineNumberTable: ...</span><br><span class="line">      LocalVariableTable:</span><br><span class="line">        Start  Length  Slot  Name   Signature</span><br><span class="line">           <span class="number">14</span>      <span class="number">10</span>     <span class="number">2</span> method   Ljava/lang/reflect/Method;</span><br><span class="line">           <span class="number">28</span>       <span class="number">4</span>     <span class="number">2</span>     e   Ljava/lang/ReflectiveOperationException;</span><br><span class="line">            <span class="number">0</span>      <span class="number">33</span>     <span class="number">0</span>  args   [Ljava/lang/String;</span><br><span class="line">            <span class="number">2</span>      <span class="number">31</span>     <span class="number">1</span>     i   I</span><br><span class="line">      StackMapTable: ...</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<h5 id="finally"><a href="#finally" class="headerlink" title="finally"></a>finally</h5><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Demo14</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> i  = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            i = <span class="number">10</span>;</span><br><span class="line">        &#125; <span class="keyword">catch</span> (Exception e) &#123;</span><br><span class="line">            i =  <span class="number">20</span>;</span><br><span class="line">        &#125; <span class="keyword">finally</span> &#123;</span><br><span class="line">            i = <span class="number">30</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(java.lang.String[])</span></span>;</span><br><span class="line">    descriptor: ([Ljava/lang/String;)V</span><br><span class="line">    flags: (<span class="number">0x0009</span>) ACC_PUBLIC, ACC_STATIC</span><br><span class="line">    Code:</span><br><span class="line">      stack=<span class="number">1</span>, locals=<span class="number">4</span>, args_size=<span class="number">1</span></span><br><span class="line">         <span class="number">0</span>: iconst_0</span><br><span class="line">         <span class="number">1</span>: istore_1</span><br><span class="line">         <span class="number">2</span>: bipush        <span class="number">10</span></span><br><span class="line">         <span class="number">4</span>: istore_1</span><br><span class="line">         <span class="number">5</span>: bipush        <span class="number">30</span></span><br><span class="line">         <span class="number">7</span>: istore_1</span><br><span class="line">         <span class="number">8</span>: goto          <span class="number">27</span></span><br><span class="line">        <span class="number">11</span>: astore_2</span><br><span class="line">        <span class="number">12</span>: bipush        <span class="number">20</span></span><br><span class="line">        <span class="number">14</span>: istore_1</span><br><span class="line">        <span class="number">15</span>: bipush        <span class="number">30</span></span><br><span class="line">        <span class="number">17</span>: istore_1</span><br><span class="line">        <span class="number">18</span>: goto          <span class="number">27</span></span><br><span class="line">        <span class="number">21</span>: astore_3</span><br><span class="line">        <span class="number">22</span>: bipush        <span class="number">30</span></span><br><span class="line">        <span class="number">24</span>: istore_1</span><br><span class="line">        <span class="number">25</span>: aload_3</span><br><span class="line">        <span class="number">26</span>: athrow</span><br><span class="line">        <span class="number">27</span>: <span class="keyword">return</span></span><br><span class="line">      Exception table:</span><br><span class="line">         from    to  target type</span><br><span class="line">             <span class="number">2</span>     <span class="number">5</span>    <span class="number">11</span>   Class java/lang/Exception</span><br><span class="line">             <span class="number">2</span>     <span class="number">5</span>    <span class="number">21</span>   any</span><br><span class="line">            <span class="number">11</span>    <span class="number">15</span>    <span class="number">21</span>   any</span><br><span class="line">      LineNumberTable:...</span><br><span class="line">      LocalVariableTable:</span><br><span class="line">        Start  Length  Slot  Name   Signature</span><br><span class="line">           <span class="number">12</span>       <span class="number">3</span>     <span class="number">2</span>     e   Ljava/lang/Exception;</span><br><span class="line">            <span class="number">0</span>      <span class="number">28</span>     <span class="number">0</span>  args   [Ljava/lang/String;</span><br><span class="line">            <span class="number">2</span>      <span class="number">26</span>     <span class="number">1</span>     i   I</span><br><span class="line">      StackMapTable: ...</span><br></pre></td></tr></table></figure>
<p>finally代码复制三份，分别放入try流程、catch流程、catch剩余的异常类型流程</p>
<h5 id="finally出现了return"><a href="#finally出现了return" class="headerlink" title="finally出现了return"></a>finally出现了return</h5><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Demo15</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">int</span> <span class="title">getResult</span> <span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="number">10</span>;</span><br><span class="line">        &#125; <span class="keyword">finally</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="number">20</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> result = getResult();</span><br><span class="line">        System.out.println(result);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">int</span> <span class="title">getResult</span><span class="params">()</span></span>;</span><br><span class="line">    descriptor: ()I</span><br><span class="line">    flags: (<span class="number">0x0009</span>) ACC_PUBLIC, ACC_STATIC</span><br><span class="line">    Code:</span><br><span class="line">      stack=<span class="number">1</span>, locals=<span class="number">2</span>, args_size=<span class="number">0</span></span><br><span class="line">         <span class="number">0</span>: bipush        <span class="number">10</span></span><br><span class="line">         <span class="number">2</span>: istore_0</span><br><span class="line">         <span class="number">3</span>: bipush        <span class="number">20</span></span><br><span class="line">         <span class="number">5</span>: ireturn</span><br><span class="line">         <span class="number">6</span>: astore_1</span><br><span class="line">         <span class="number">7</span>: bipush        <span class="number">20</span></span><br><span class="line">         <span class="number">9</span>: ireturn</span><br><span class="line">      Exception table:</span><br><span class="line">         from    to  target type</span><br><span class="line">             <span class="number">0</span>     <span class="number">3</span>     <span class="number">6</span>   any</span><br><span class="line">      LineNumberTable:...</span><br><span class="line">      StackMapTable: ...</span><br></pre></td></tr></table></figure>
<ul>
<li>finally中的ireturn被插入了所有可能的流程，英雌返回结果肯定以finally的为准</li>
<li>字节码istore_0 暂存slot 0，目的是为了固定返回值</li>
<li>finally中出现了return，会吞掉异常</li>
</ul>
<h6 id="finallly对返回值的影响"><a href="#finallly对返回值的影响" class="headerlink" title="finallly对返回值的影响"></a>finallly对返回值的影响</h6><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Demo16</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">int</span> <span class="title">getResult</span> <span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> i = <span class="number">10</span>;</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> i;</span><br><span class="line">        &#125; <span class="keyword">finally</span> &#123;</span><br><span class="line">            i = <span class="number">20</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> result = getResult();</span><br><span class="line">        System.out.println(result);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"> <span class="number">0</span>: bipush        <span class="number">10</span>     <span class="comment">// &lt;= 10 放入栈顶</span></span><br><span class="line"> <span class="number">2</span>: istore_0             <span class="comment">// 10 =&gt;  i</span></span><br><span class="line"> <span class="number">3</span>: iload_0              <span class="comment">// &lt;=  i(10)</span></span><br><span class="line"> <span class="number">4</span>: istore_1             <span class="comment">// 10 =&gt; slot1 暂存slot1，目标是为了固定返回值</span></span><br><span class="line"> <span class="number">5</span>: bipush        <span class="number">20</span>     <span class="comment">//  &lt;= 20 放入栈顶</span></span><br><span class="line"> <span class="number">7</span>: istore_0             <span class="comment">// 20 =&gt;  i</span></span><br><span class="line"> <span class="number">8</span>: iload_1              <span class="comment">// &lt;= slot1（10）载入slot1暂存的值</span></span><br><span class="line"> <span class="number">9</span>: ireturn              <span class="comment">// 返回栈顶的int(10)</span></span><br><span class="line"><span class="number">10</span>: astore_2</span><br><span class="line"><span class="number">11</span>: bipush        <span class="number">20</span></span><br><span class="line"><span class="number">13</span>: istore_0</span><br><span class="line"><span class="number">14</span>: aload_2</span><br><span class="line"><span class="number">15</span>: athrow</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<h4 id="synchronized"><a href="#synchronized" class="headerlink" title="synchronized"></a>synchronized</h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Demo17</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        Object lock = <span class="keyword">new</span> Object();</span><br><span class="line">        <span class="keyword">synchronized</span> (lock) &#123;</span><br><span class="line">            System.out.println(<span class="string">&quot;lock&quot;</span>);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(java.lang.String[])</span></span>;</span><br><span class="line">    descriptor: ([Ljava/lang/String;)V</span><br><span class="line">    flags: (<span class="number">0x0009</span>) ACC_PUBLIC, ACC_STATIC</span><br><span class="line">    Code:</span><br><span class="line">      stack=<span class="number">2</span>, locals=<span class="number">4</span>, args_size=<span class="number">1</span></span><br><span class="line">         0: new           #2                  // class java/lang/Object</span><br><span class="line">         <span class="number">3</span>: dup</span><br><span class="line">         4: invokespecial #1                  // Method java/lang/Object.&quot;&lt;init&gt;&quot;:()V</span><br><span class="line">         <span class="number">7</span>: astore_1</span><br><span class="line">         <span class="number">8</span>: aload_1</span><br><span class="line">         <span class="number">9</span>: dup</span><br><span class="line">        <span class="number">10</span>: astore_2</span><br><span class="line">        <span class="number">11</span>: monitorenter</span><br><span class="line">        12: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;</span><br><span class="line">        15: ldc           #4                  // String lock</span><br><span class="line">        17: invokevirtual #5                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V</span><br><span class="line">        <span class="number">20</span>: aload_2</span><br><span class="line">        <span class="number">21</span>: monitorexit</span><br><span class="line">        <span class="number">22</span>: goto          <span class="number">30</span></span><br><span class="line">        <span class="number">25</span>: astore_3</span><br><span class="line">        <span class="number">26</span>: aload_2</span><br><span class="line">        <span class="number">27</span>: monitorexit</span><br><span class="line">        <span class="number">28</span>: aload_3</span><br><span class="line">        <span class="number">29</span>: athrow</span><br><span class="line">        <span class="number">30</span>: <span class="keyword">return</span></span><br><span class="line">      Exception table:</span><br><span class="line">         from    to  target type</span><br><span class="line">            <span class="number">12</span>    <span class="number">22</span>    <span class="number">25</span>   any</span><br><span class="line">            <span class="number">25</span>    <span class="number">28</span>    <span class="number">25</span>   any</span><br><span class="line">      LineNumberTable: ...</span><br><span class="line">      LocalVariableTable:</span><br><span class="line">        Start  Length  Slot  Name   Signature</span><br><span class="line">            <span class="number">0</span>      <span class="number">31</span>     <span class="number">0</span>  args   [Ljava/lang/String;</span><br><span class="line">            <span class="number">8</span>      <span class="number">23</span>     <span class="number">1</span>  lock   Ljava/lang/Object;</span><br><span class="line">      StackMapTable: ...</span><br></pre></td></tr></table></figure>
<blockquote>
<p>方法级别的synchronized不会在字节码指令中有所体现</p>
</blockquote>
<h3 id="3-编译期处理"><a href="#3-编译期处理" class="headerlink" title="3. 编译期处理"></a>3. 编译期处理</h3><p> 语法糖，其实就是指java编译器<em>.java源码编译为 </em>.class字节码的过程中，自动生成和转换的一些代码。</p>
<h4 id="默认构造器"><a href="#默认构造器" class="headerlink" title="默认构造器"></a>默认构造器</h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Candy1</span> </span>&#123;&#125;</span><br></pre></td></tr></table></figure>
<p>编译成class后的代码</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Candy1</span> </span>&#123;</span><br><span class="line">    <span class="comment">// 这个无参构造是编译器帮助我们加上的</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">Candy1</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    <span class="keyword">super</span>(); <span class="comment">// 即调用父类 Object 的无参构造方法，即调用 java/lang/Object.&quot;</span></span><br><span class="line">    &lt;init&gt;<span class="string">&quot;:()V</span></span><br><span class="line"><span class="string">    &#125;</span></span><br><span class="line"><span class="string">&#125;</span></span><br></pre></td></tr></table></figure>
<h4 id="自动拆装箱"><a href="#自动拆装箱" class="headerlink" title="自动拆装箱"></a>自动拆装箱</h4><p>JDK5开始加入</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Candy2</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        Integer x = <span class="number">1</span>;</span><br><span class="line">        <span class="keyword">int</span> y = x;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Candy2</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        Integer x = Integer.valueOf(<span class="number">1</span>);</span><br><span class="line">        <span class="keyword">int</span> y = x.intValue();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h4 id="泛型集合取值"><a href="#泛型集合取值" class="headerlink" title="泛型集合取值"></a>泛型集合取值</h4><p>JDK5加入的，但java在编译泛型代码会执行<code>泛型擦除</code>，即泛型信息在编译为字节码之后的就丢失了，实际的类型都当作了Object类型处理</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Candy3</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        List&lt;Integer&gt; list = <span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line">        list.add(<span class="number">10</span>); <span class="comment">// 实际调用的是 List.add(Object e)</span></span><br><span class="line">        Integer x = list.get(<span class="number">0</span>); <span class="comment">// 实际调用的是 Object obj = List.get(int index);</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>在取值时编译器真正生成的字节码中，还要额外做类型转换的操作</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 需要将 Object 转为 Integer</span></span><br><span class="line">Integer x = (Integer)list.get(<span class="number">0</span>);</span><br></pre></td></tr></table></figure>
<p>擦除的是字节码上的泛型信息，可以看到LocalVariableType任然保留了方法参数泛型的信息，使用反射能够获得这些信息。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Reflect2</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> Set&lt;Integer&gt; <span class="title">test</span><span class="params">(List&lt;String&gt; list, Map&lt;Integer, Map&lt;Integer, Object&gt;&gt; map)</span></span>&#123;<span class="keyword">return</span> <span class="keyword">null</span>;&#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> <span class="keyword">throws</span> NoSuchMethodException </span>&#123;</span><br><span class="line">        Method test = Reflect2.class.getMethod(<span class="string">&quot;test&quot;</span>, List.class, Map.class);</span><br><span class="line">        Type[] genericParameterTypes = test.getGenericParameterTypes();</span><br><span class="line">        <span class="keyword">for</span> (Type genericParameterType : genericParameterTypes) &#123;</span><br><span class="line">            <span class="keyword">if</span> (genericParameterType <span class="keyword">instanceof</span> ParameterizedType) &#123;</span><br><span class="line">                ParameterizedType parameterizedType = (ParameterizedType)genericParameterType;</span><br><span class="line">                System.out.println(<span class="string">&quot;原ss始类型&quot;</span> + parameterizedType.getRawType());</span><br><span class="line">                Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();</span><br><span class="line">                <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; actualTypeArguments.length; i++) &#123;</span><br><span class="line">                    System.out.printf(<span class="string">&quot;原始参数类型[%d] - %s\n&quot;</span>, i, actualTypeArguments[i]);</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h4 id="可变参数"><a href="#可变参数" class="headerlink" title="可变参数"></a>可变参数</h4><p>可变参数<code>String... args</code>JDK5加入，其实就是一个<code>Stirng[] args</code></p>
<blockquote>
<p>foo(Stirng… args) {}</p>
<p>如果调用foo()则等价于foo(new String[]{})，创建了一个空的数组，而不会传递null</p>
</blockquote>
<h4 id="foreach循环"><a href="#foreach循环" class="headerlink" title="foreach循环"></a>foreach循环</h4><p>JDK5加入</p>
<blockquote>
<p>froeach 循环写法，能够配合数组，以及所有实现了<code>Iterable</code>接口的集合类一起使用，其中<code>Iterable</code>用来获取集合的迭代器（<code>Iterator</code>）</p>
</blockquote>
<h4 id="switch字符串"><a href="#switch字符串" class="headerlink" title="switch字符串"></a>switch字符串</h4><p>从JDK7开始，switch可以用于字符串和枚举类</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Candy6_1</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">choose</span><span class="params">(String str)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">switch</span> (str) &#123;</span><br><span class="line">            <span class="keyword">case</span> <span class="string">&quot;hello&quot;</span>: &#123;</span><br><span class="line">            	System.out.println(<span class="string">&quot;h&quot;</span>);</span><br><span class="line">            	<span class="keyword">break</span>;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">case</span> <span class="string">&quot;world&quot;</span>: &#123;</span><br><span class="line">            	System.out.println(<span class="string">&quot;w&quot;</span>);</span><br><span class="line">            	<span class="keyword">break</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>会被编译器转换为：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Candy6_1</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">Candy6_1</span><span class="params">()</span> </span>&#123;&#125;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">choose</span><span class="params">(String str)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">byte</span> x = -<span class="number">1</span>;</span><br><span class="line">        <span class="keyword">switch</span>(str.hashCode()) &#123;</span><br><span class="line">            <span class="keyword">case</span> <span class="number">99162322</span>: <span class="comment">// hello 的 hashCode</span></span><br><span class="line">                <span class="keyword">if</span> (str.equals(<span class="string">&quot;hello&quot;</span>)) &#123;</span><br><span class="line">                    x = <span class="number">0</span>;</span><br><span class="line">                &#125;</span><br><span class="line">                <span class="keyword">break</span>;</span><br><span class="line">            <span class="keyword">case</span> <span class="number">113318802</span>: <span class="comment">// world 的 hashCode</span></span><br><span class="line">                <span class="keyword">if</span> (str.equals(<span class="string">&quot;world&quot;</span>)) &#123;</span><br><span class="line">                	x = <span class="number">1</span>;</span><br><span class="line">                &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">switch</span>(x) &#123;</span><br><span class="line">            <span class="keyword">case</span> <span class="number">0</span>:</span><br><span class="line">                System.out.println(<span class="string">&quot;h&quot;</span>);</span><br><span class="line">                <span class="keyword">break</span>;</span><br><span class="line">            <span class="keyword">case</span> <span class="number">1</span>:</span><br><span class="line">            	System.out.println(<span class="string">&quot;w&quot;</span>);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>执行了两遍switch，第一遍是根据字符串的hashCode和equals将字符串的转换为相应的byte类型；第二遍才是利用byte执行进行比较。</p>
<p>为什么第一遍必须即比较hashCode，又利用equals比较呢？hashCode是为了提高效率，减少可能的比较；而equals是为了防止hashCode的冲突</p>
<h4 id="switch枚举"><a href="#switch枚举" class="headerlink" title="switch枚举"></a>switch枚举</h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">enum</span> <span class="title">Sex</span> </span>&#123;</span><br><span class="line">	MALE, FEMALE</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Candy7</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">foo</span><span class="params">(Sex sex)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">switch</span> (sex) &#123;</span><br><span class="line">            <span class="keyword">case</span> MALE:</span><br><span class="line">            	System.out.println(<span class="string">&quot;男&quot;</span>); <span class="keyword">break</span>;</span><br><span class="line">            <span class="keyword">case</span> FEMALE:</span><br><span class="line">            	System.out.println(<span class="string">&quot;女&quot;</span>); <span class="keyword">break</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>转换后代码：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Candy7</span> </span>&#123;</span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">    * 定义一个合成类（仅 jvm 使用，对我们不可见）</span></span><br><span class="line"><span class="comment">    * 用来映射枚举的 ordinal 与数组元素的关系</span></span><br><span class="line"><span class="comment">    * 枚举的 ordinal 表示枚举对象的序号，从 0 开始</span></span><br><span class="line"><span class="comment">    * 即 MALE 的 ordinal()=0，FEMALE 的 ordinal()=1</span></span><br><span class="line"><span class="comment">    */</span></span><br><span class="line">    <span class="keyword">static</span> <span class="class"><span class="keyword">class</span> $<span class="title">MAP</span> </span>&#123;</span><br><span class="line">        <span class="comment">// 数组大小即为枚举元素个数，里面存储case用来对比的数字</span></span><br><span class="line">        <span class="keyword">static</span> <span class="keyword">int</span>[] map = <span class="keyword">new</span> <span class="keyword">int</span>[<span class="number">2</span>];</span><br><span class="line">        <span class="keyword">static</span> &#123;</span><br><span class="line">            map[Sex.MALE.ordinal()] = <span class="number">1</span>;</span><br><span class="line">            map[Sex.FEMALE.ordinal()] = <span class="number">2</span>;</span><br><span class="line">        &#125;</span><br><span class="line">     &#125;</span><br><span class="line">     <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">foo</span><span class="params">(Sex sex)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> x = $MAP.map[sex.ordinal()];</span><br><span class="line">        <span class="keyword">switch</span> (x) &#123;</span><br><span class="line">            <span class="keyword">case</span> <span class="number">1</span>:</span><br><span class="line">            	System.out.println(<span class="string">&quot;男&quot;</span>);</span><br><span class="line">            <span class="keyword">break</span>;</span><br><span class="line">            <span class="keyword">case</span> <span class="number">2</span>:</span><br><span class="line">            	System.out.println(<span class="string">&quot;女&quot;</span>);</span><br><span class="line">            <span class="keyword">break</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h4 id="枚举类"><a href="#枚举类" class="headerlink" title="枚举类"></a>枚举类</h4><p>JDK7新增枚举类</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">enum</span> <span class="title">Sex</span> </span>&#123;</span><br><span class="line">	MALE, FEMALE</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">final</span> <span class="class"><span class="keyword">class</span> <span class="title">Sex</span> <span class="keyword">extends</span> <span class="title">Enum</span>&lt;<span class="title">Sex</span>&gt; </span>&#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">final</span> Sex MALE;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">final</span> Sex FEMALE;</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">final</span> Sex[] $VALUES;</span><br><span class="line">    <span class="keyword">static</span> &#123;</span><br><span class="line">        MALE = <span class="keyword">new</span> Sex(<span class="string">&quot;MALE&quot;</span>, <span class="number">0</span>);</span><br><span class="line">        FEMALE = <span class="keyword">new</span> Sex(<span class="string">&quot;FEMALE&quot;</span>, <span class="number">1</span>);</span><br><span class="line">        $VALUES = <span class="keyword">new</span> Sex[]&#123;MALE, FEMALE&#125;;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">    * Sole constructor. Programmers cannot invoke this constructor.</span></span><br><span class="line"><span class="comment">    * It is for use by code emitted by the compiler in response to</span></span><br><span class="line"><span class="comment">    * enum type declarations.</span></span><br><span class="line"><span class="comment">    *</span></span><br><span class="line"><span class="comment">    * <span class="doctag">@param</span> name - The name of this enum constant, which is the identifier</span></span><br><span class="line"><span class="comment">    * used to declare it.</span></span><br><span class="line"><span class="comment">    * <span class="doctag">@param</span> ordinal - The ordinal of this enumeration constant (its position</span></span><br><span class="line"><span class="comment">    * in the enum declaration, where the initial constant is</span></span><br><span class="line"><span class="comment">    assigned</span></span><br><span class="line"><span class="comment">    */</span></span><br><span class="line">    <span class="function"><span class="keyword">private</span> <span class="title">Sex</span><span class="params">(String name, <span class="keyword">int</span> ordinal)</span> </span>&#123;</span><br><span class="line">    	<span class="keyword">super</span>(name, ordinal);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> Sex[] values() &#123;</span><br><span class="line">    	<span class="keyword">return</span> $VALUES.clone();</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> Sex <span class="title">valueOf</span><span class="params">(String name)</span> </span>&#123;</span><br><span class="line">    	<span class="keyword">return</span> Enum.valueOf(Sex.class, name);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h4 id="try-with-resources"><a href="#try-with-resources" class="headerlink" title="try-with-resources"></a>try-with-resources</h4><p>JDK7开始新增了对需要关闭的资源处理的特殊语法try-with-resources：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">try</span> (资源变量 = 创建资源对象) &#123;&#125; <span class="keyword">catch</span> () &#123;&#125;</span><br></pre></td></tr></table></figure>
<p>其中资源对象需要实现<code>AutoCloseable</code>接口，使用<code>try-with-resources</code>可以不用写finally语句块，编译器会帮助生成关闭资源代码.</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Candy9</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">try</span>(InputStream is = <span class="keyword">new</span> FileInputStream(<span class="string">&quot;d:\\1.txt&quot;</span>)) &#123;</span><br><span class="line">        	System.out.println(is);</span><br><span class="line">        &#125; <span class="keyword">catch</span> (IOException e) &#123;</span><br><span class="line">        	e.printStackTrace();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>转换为：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Candy9</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">Candy9</span><span class="params">()</span> </span>&#123;&#125;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            InputStream is = <span class="keyword">new</span> FileInputStream(<span class="string">&quot;d:\\1.txt&quot;</span>);</span><br><span class="line">            Throwable t = <span class="keyword">null</span>;</span><br><span class="line">            <span class="keyword">try</span> &#123;</span><br><span class="line">                System.out.println(is);</span><br><span class="line">            &#125; <span class="keyword">catch</span> (Throwable e1) &#123;</span><br><span class="line">                <span class="comment">// t 是我们代码出现的异常</span></span><br><span class="line">                t = e1;</span><br><span class="line">                <span class="keyword">throw</span> e1;</span><br><span class="line">            &#125; <span class="keyword">finally</span> &#123;</span><br><span class="line">                <span class="comment">// 判断资源不为空</span></span><br><span class="line">                <span class="keyword">if</span> (is != <span class="keyword">null</span> )&#123;</span><br><span class="line">                    <span class="keyword">if</span> (t != <span class="keyword">null</span>) &#123;</span><br><span class="line">                        <span class="keyword">try</span> &#123;</span><br><span class="line">                            is.close();</span><br><span class="line">                        &#125; <span class="keyword">catch</span> (Throwable e2) &#123;</span><br><span class="line">                            <span class="comment">// 如果close出现异常，作为被压制异常添加</span></span><br><span class="line">                            t.addSuppressed(e2);</span><br><span class="line">                        &#125;</span><br><span class="line">                    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                        is.close();</span><br><span class="line">                    &#125;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125; <span class="keyword">catch</span> (IOException e) &#123;</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p><code>addSuppressed(Throwable e)</code>（添加被压制异常）？是为了防止异常信息的丢失</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Test6</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">try</span> (MyResource resource = <span class="keyword">new</span> MyResource()) &#123;</span><br><span class="line">        	<span class="keyword">int</span> i = <span class="number">1</span>/<span class="number">0</span>;</span><br><span class="line">        &#125; <span class="keyword">catch</span> (Exception e) &#123;</span><br><span class="line">        	e.printStackTrace();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">MyResource</span> <span class="keyword">implements</span> <span class="title">AutoCloseable</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">close</span><span class="params">()</span> <span class="keyword">throws</span> Exception </span>&#123;</span><br><span class="line">    	<span class="keyword">throw</span> <span class="keyword">new</span> Exception(<span class="string">&quot;close 异常&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">java.lang.ArithmeticException: / by zero</span><br><span class="line">at test.Test6.main(Test6.java:7)</span><br><span class="line">Suppressed: java.lang.Exception: close 异常</span><br><span class="line">at test.MyResource.close(Test6.java:18)</span><br><span class="line">at test.Test6.main(Test6.java:6</span><br></pre></td></tr></table></figure>
<p>两个异常不会丢失</p>
<h4 id="方法重写时的桥接方法"><a href="#方法重写时的桥接方法" class="headerlink" title="方法重写时的桥接方法"></a>方法重写时的桥接方法</h4><p>方法重写时对返回值分两种情况：</p>
<ul>
<li>父子类的返回值完全一致</li>
<li>子类返回值可以时父类返回值的子类</li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">A</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> Number <span class="title">m</span><span class="params">()</span> </span>&#123;<span class="keyword">return</span> <span class="number">1</span>;&#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">B</span> <span class="keyword">extends</span> <span class="title">A</span> </span>&#123;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="comment">// 子类 m 方法的返回值是 Integer 是父类 m 方法返回值 Number 的子类</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> Integer <span class="title">m</span><span class="params">()</span> </span>&#123;<span class="keyword">return</span> <span class="number">2</span>;&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>对于子类，java编译器会做处理</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">B</span> <span class="keyword">extends</span> <span class="title">A</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> Integer <span class="title">m</span><span class="params">()</span> </span>&#123;<span class="keyword">return</span> <span class="number">2</span>;&#125;</span><br><span class="line">    <span class="comment">// 此方法才是真正重写了父类 public Number m() 方法</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> synthetic bridge Number <span class="title">m</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="comment">// 调用 public Integer m()</span></span><br><span class="line">        <span class="keyword">return</span> m();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h4 id="匿名内部类"><a href="#匿名内部类" class="headerlink" title="匿名内部类"></a>匿名内部类</h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Candy11</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        Runnable runnable = <span class="keyword">new</span> Runnable() &#123;</span><br><span class="line">            <span class="meta">@Override</span></span><br><span class="line">            <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">run</span><span class="params">()</span> </span>&#123;</span><br><span class="line">                System.out.println(<span class="string">&quot;ok&quot;</span>);</span><br><span class="line">            &#125;</span><br><span class="line">    &#125;;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>转换后代码：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 额外生成的类</span></span><br><span class="line"><span class="keyword">final</span> <span class="class"><span class="keyword">class</span> <span class="title">Candy11</span>$1 <span class="keyword">implements</span> <span class="title">Runnable</span> </span>&#123;</span><br><span class="line">    Candy11$<span class="number">1</span>() &#123;&#125;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">run</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    	System.out.println(<span class="string">&quot;ok&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Candy11</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        Runnable runnable = <span class="keyword">new</span> Candy11$<span class="number">1</span>();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>引用局部变量的匿名内部类</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Candy11</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">test</span><span class="params">(<span class="keyword">final</span> <span class="keyword">int</span> x)</span> </span>&#123;</span><br><span class="line">        Runnable runnable = <span class="keyword">new</span> Runnable() &#123;</span><br><span class="line">            <span class="meta">@Override</span></span><br><span class="line">            <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">run</span><span class="params">()</span> </span>&#123;</span><br><span class="line">                System.out.println(<span class="string">&quot;ok:&quot;</span> + x);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>转换后</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">final</span> <span class="class"><span class="keyword">class</span> <span class="title">Candy11</span>$1 <span class="keyword">implements</span> <span class="title">Runnable</span> </span>&#123;</span><br><span class="line">    <span class="keyword">int</span> val$x;</span><br><span class="line">    Candy11$<span class="number">1</span>(<span class="keyword">int</span> x) &#123;</span><br><span class="line">        <span class="keyword">this</span>.val$x = x;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">run</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;ok:&quot;</span> + <span class="keyword">this</span>.val$x);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Candy11</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">test</span><span class="params">(<span class="keyword">final</span> <span class="keyword">int</span> x)</span> </span>&#123;</span><br><span class="line">        Runnable runnable = <span class="keyword">new</span> Candy11$<span class="number">1</span>(x);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<blockquote>
<p>匿名内部类引用局部变量时，局部变量必须时final的：因为在创建Candy11$1对象时，将x的值赋值给了val$x属性，所以x不应该再发生变化了，如果变化，那么val$x属性没有机会跟着一起变化</p>
</blockquote>
<h3 id="4-类加载阶段"><a href="#4-类加载阶段" class="headerlink" title="4. 类加载阶段"></a>4. 类加载阶段</h3><h5 id="4-1-加载"><a href="#4-1-加载" class="headerlink" title="4.1 加载"></a>4.1 加载</h5><ul>
<li>将类的字节码载入方法区中，内部采用C++的instanceKlass描述java类重要的field有：<ul>
<li>_java_mirror：即java的类镜像，例如Stirng来说，就是String.class，作用是把klass暴露给java使用</li>
<li>_super：即父类</li>
<li>_fields：即成员变量</li>
<li>_methods：即方法</li>
<li>_constants：即常量池</li>
<li>_class_loader：即类的加载器</li>
<li>_vtable：虚方法表</li>
<li>_itable：接口方法表</li>
</ul>
</li>
<li>如果这个类还有父类没有加载，先加载父类</li>
<li>加载和链接可能交替运行的</li>
</ul>
<blockquote>
<p>instanceKlass这样的【元数据】是存储在方法区（1.8后的元空间中），但_java_mirror是存储在堆中的</p>
</blockquote>
<p><img src="image-20211029162053782.png" alt="image-20211029162053782"></p>
<h5 id="4-2-链接"><a href="#4-2-链接" class="headerlink" title="4.2 链接"></a>4.2 链接</h5><h6 id="验证"><a href="#验证" class="headerlink" title="验证"></a>验证</h6><p>验证类是否符合JVM规范，安全性检查</p>
<h6 id="准备"><a href="#准备" class="headerlink" title="准备"></a>准备</h6><p>为static变量分配空间，设置默认值</p>
<ul>
<li>static变量在JDK7之前存储于instanceKlass末尾，从JDK7开始，存储于_java_mrrior末尾</li>
<li>static变量分配空间和赋值是两个步骤，分配空间在准备阶段完成，赋值在初始化阶段完成。</li>
<li>如果static变量是final的基本类型，以及字符串常量，那么编译阶段就确定了，赋值在准备阶段完成</li>
<li>如果static变量是final的，但属于引用类型，那么赋值也会在初始化阶段完成</li>
</ul>
<h6 id="解析"><a href="#解析" class="headerlink" title="解析"></a>解析</h6><p>将常量池中的符号引用解析为直接引用</p>
<p><img src="image-20211102092855327.png" alt="image-20211102092855327"></p>
<p>loadClass方法不会导致类的解析和初始化</p>
<h5 id="4-3-初始化"><a href="#4-3-初始化" class="headerlink" title="4.3 初始化"></a>4.3 初始化</h5><h6 id="lt-cinit-gt-V方法"><a href="#lt-cinit-gt-V方法" class="headerlink" title="&lt;cinit&gt;()V方法"></a><code>&lt;cinit&gt;()V</code>方法</h6><p>初始化即调用<code>&lt;cinit&gt;()V</code>，虚拟机会保证这个类的构造方法线程安全</p>
<h6 id="发生的时机"><a href="#发生的时机" class="headerlink" title="发生的时机"></a>发生的时机</h6><p>类初始化是懒惰的</p>
<p>会导致初始化的情况 </p>
<ul>
<li>main方法所在的类，总会被首先初始化</li>
<li>首次访问这个类的静态变量或静态方法时</li>
<li>子类初始化，如果父类还初始化，会引发</li>
<li>子类访问父类的静态变量，会触发父类的初始化</li>
<li>Class.forName</li>
<li>new 会导致初始化</li>
</ul>
<p>不会导致初始化的情况</p>
<ul>
<li>访问类的static final静态常量（基本类型和字符串）不会触发初始化</li>
<li>类对象.class不会触发初始化</li>
<li>创建该类的数组不会触发初始化</li>
<li>类加载器的loadClass方法</li>
<li>Class.forName的参数2为false时</li>
</ul>
<h3 id="5-类加载器"><a href="#5-类加载器" class="headerlink" title="5. 类加载器"></a>5. 类加载器</h3><div class="table-container">
<table>
<thead>
<tr>
<th>名称</th>
<th>加载类路径</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr>
<td>Bootstrap ClassLoader</td>
<td>JAVA_HOME/jre/lib</td>
<td>无法直接访问</td>
</tr>
<tr>
<td>Extension ClassLoader</td>
<td>JAVA_HOME/jre/lib/ext</td>
<td>上级为Bootstrap，显示为null</td>
</tr>
<tr>
<td>Application ClassLoader</td>
<td>calsspath</td>
<td>上级为Extension</td>
</tr>
<tr>
<td>自定义类加载器</td>
<td>自定义</td>
<td>上级为Appliction</td>
</tr>
</tbody>
</table>
</div>
<h4 id="双亲委派模式"><a href="#双亲委派模式" class="headerlink" title="双亲委派模式"></a>双亲委派模式</h4><p>所谓的双亲委派，就是指调用类加载器的loadClass方法时，查找类的规则。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">protected</span> Class&lt;?&gt; loadClass(String name, <span class="keyword">boolean</span> resolve)</span><br><span class="line">        <span class="keyword">throws</span> ClassNotFoundException</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">synchronized</span> (getClassLoadingLock(name)) &#123;</span><br><span class="line">            <span class="comment">// 1. 检查该类是否已经加载</span></span><br><span class="line">            Class&lt;?&gt; c = findLoadedClass(name);</span><br><span class="line">            <span class="keyword">if</span> (c == <span class="keyword">null</span>) &#123;</span><br><span class="line">                <span class="keyword">long</span> t0 = System.nanoTime();</span><br><span class="line">                <span class="keyword">try</span> &#123;</span><br><span class="line">                    <span class="keyword">if</span> (parent != <span class="keyword">null</span>) &#123;</span><br><span class="line">                        <span class="comment">// 2. 有上级的，委派上级loadClass</span></span><br><span class="line">                        c = parent.loadClass(name, <span class="keyword">false</span>);</span><br><span class="line">                    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                        <span class="comment">// 3. 没有上级ExtClassLoader，则委派BootstrapClassLoader</span></span><br><span class="line">                        c = findBootstrapClassOrNull(name);</span><br><span class="line">                    &#125;</span><br><span class="line">                &#125; <span class="keyword">catch</span> (ClassNotFoundException e) &#123;</span><br><span class="line">                 </span><br><span class="line">                &#125;</span><br><span class="line"></span><br><span class="line">                <span class="keyword">if</span> (c == <span class="keyword">null</span>) &#123;</span><br><span class="line">                    <span class="keyword">long</span> t1 = System.nanoTime();</span><br><span class="line">                    <span class="comment">// 4. 每层到不到，调用finalClass方法（每个类加载器自己扩展）来加载</span></span><br><span class="line">                    c = findClass(name);</span><br><span class="line"> sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);</span><br><span class="line">                    sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);</span><br><span class="line">                    sun.misc.PerfCounter.getFindClasses().increment();</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">if</span> (resolve) &#123;</span><br><span class="line">                resolveClass(c);</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">return</span> c;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Load2</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> <span class="keyword">throws</span> ClassNotFoundException </span>&#123;</span><br><span class="line">        Class&lt;?&gt; aClass = Load2.class.getClassLoader().loadClass(<span class="string">&quot;cn.pzaily.jvm.candy.Candy9&quot;</span>);</span><br><span class="line">        System.out.println(aClass.getClassLoader());</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>执行流程：</p>
<ol>
<li><p><code>sum.misc.Launcher$AppClassLoader</code> // 1处，开始查看已加载的类，结果没有</p>
</li>
<li><p><code>sum.misc.Launcher$AppClassLoader</code> // 2处，委派上级</p>
<p><code>sum.misc.Launcher$ExtClassLoader.loadClass()</code></p>
</li>
<li><p><code>sum.misc.Launcher$ExtClassLoader</code> //1处，查看已加载的类，结果没有</p>
</li>
<li><p><code>sum.misc.Launcher4ExtClassLoader</code> // 3处，没有了上级，则委派<code>BootstrapClassLoader</code>查找</p>
</li>
<li><p><code>BootstrapClassLoader</code>在JAVA_HOME/jre/lib没有找到Candy9类，没有</p>
</li>
<li><p><code>sum.misc.Launcher$ExtClassLoader</code> //4处，调用自己的findClass方法，是在JAVA_HOMR/jre/lib/ext下找到这个类，没有，回到<code>sum.misc.Launcher$AppClassLoader</code> // 2处</p>
</li>
<li><p>继续执行<code>sum.misc.Launcher$AppClassLoader</code> // 4处，调用它自己的findClass方法，在classpath下查找。</p>
</li>
</ol>
<h4 id="线程上下文类加载周期"><a href="#线程上下文类加载周期" class="headerlink" title="线程上下文类加载周期"></a>线程上下文类加载周期</h4><h4 id="自定义类加载器"><a href="#自定义类加载器" class="headerlink" title="自定义类加载器"></a>自定义类加载器</h4><p>什么时候需要自定义类加载器</p>
<ul>
<li>想加载非classpath任意路径中的类文件</li>
<li>都是通过接口来使用实现，希望解耦时，常用在框架设计</li>
<li>这些类希望予以隔离，不同应用的同名类都可以加载不冲突，常见于tomccat容器</li>
</ul>
<p>步骤</p>
<ol>
<li>继承ClassLoader父类</li>
<li>要遵从双亲委派机制，重写findClass方法<ol>
<li>注意不是重写loadClass方法，否则不会走双亲委派机制</li>
</ol>
</li>
<li>读取类文件的字节码</li>
<li>调用父类的defineClass方法来加载类</li>
<li>使用者调用该类加载器的loadClass方法</li>
</ol>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Load3</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        MyClassLoader classLoader1 = <span class="keyword">new</span> MyClassLoader();</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            Class&lt;?&gt; demo1 = classLoader1.loadClass(<span class="string">&quot;cn.pzaily.jvm.load.Dome&quot;</span>);</span><br><span class="line">            System.out.println(demo1);</span><br><span class="line">        &#125; <span class="keyword">catch</span> (ClassNotFoundException e) &#123;</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">MyClassLoader</span> <span class="keyword">extends</span> <span class="title">ClassLoader</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">protected</span> Class&lt;?&gt; findClass(String name) <span class="keyword">throws</span> ClassNotFoundException &#123;</span><br><span class="line"></span><br><span class="line">        String path = <span class="string">&quot;F:\\ideaProject\\practice\\jvm\\src\\main\\java\\&quot;</span> + name.replace(<span class="string">&quot;.&quot;</span>, <span class="string">&quot;\\&quot;</span>) + <span class="string">&quot;.class&quot;</span>;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">try</span> (ByteArrayOutputStream os = <span class="keyword">new</span> ByteArrayOutputStream()) &#123;</span><br><span class="line"></span><br><span class="line">            Files.copy(Paths.get(path), os);</span><br><span class="line"></span><br><span class="line">            <span class="keyword">byte</span>[] bytes = os.toByteArray();</span><br><span class="line"></span><br><span class="line">            Class&lt;?&gt; aClass = defineClass(name, bytes, <span class="number">0</span>, bytes.length);</span><br><span class="line"></span><br><span class="line">            <span class="keyword">return</span> aClass;</span><br><span class="line"></span><br><span class="line">        &#125; <span class="keyword">catch</span> (IOException e) &#123;</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">            <span class="keyword">throw</span> <span class="keyword">new</span> ClassNotFoundException(<span class="string">&quot;没有找到&quot;</span> + path + <span class="string">&quot;文件&quot;</span>);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h3 id="6-运行期优化"><a href="#6-运行期优化" class="headerlink" title="6. 运行期优化"></a>6. 运行期优化</h3><h4 id="即时编译"><a href="#即时编译" class="headerlink" title="即时编译"></a>即时编译</h4><h4 id="分层编译"><a href="#分层编译" class="headerlink" title="分层编译"></a>分层编译</h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">JIT1</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; <span class="number">200</span>; i++) &#123;</span><br><span class="line">            <span class="keyword">long</span> start = System.nanoTime();</span><br><span class="line">            <span class="keyword">for</span> (<span class="keyword">int</span> j = <span class="number">0</span>; j &lt; <span class="number">10000</span>; j++) &#123;</span><br><span class="line">                <span class="keyword">new</span> Object();</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">long</span> end = System.nanoTime();</span><br><span class="line">            System.out.println(i + <span class="string">&quot;\t&quot;</span> + (end - start));</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p><img src="image-20211030163808965.png" alt="image-20211030163808965"></p>
<p><img src="image-20211030163852827.png" alt="image-20211030163852827"></p>
<p>JVM将执行状态分成了5个层次</p>
<ul>
<li>0 层，解释执行（Interpreter）</li>
<li>1层，使用C1即时编译器编译执行（不带profiling）</li>
<li>2层，使用C1即时编译器编译执行（带基本的profiling）</li>
<li>3层，使用C1即时编译器编译执行（带完全的profiling）</li>
<li>4层，使用C2即时编译器编译执行</li>
</ul>
<blockquote>
<p>profiling是指在运行过程中收集一些程序执行状态的数据，例如【方法的调用次数】，【循环的回边次数】等</p>
</blockquote>
<p>即时编译器（JIT）于解释器的区别</p>
<ul>
<li>解释器是将字节码解释为机器码，下次即时遭遇相同的字节码，仍会执行重复的解释</li>
<li>JIT是将一些字节码编译成机器码，并存入Code Cache，下次遇到相同的代码，执行执行，无需再编译</li>
<li>解释器是将字节码解释为针对所有平台都通用的机器码</li>
<li>JIT会根据平台类型，生成平台特定的机器码</li>
</ul>
<p>优化的手段称为【逃逸分析】，发现新建的对象是否逃逸。可以使用<code>-XX:-DoEscapeAnalysis</code>关闭逃逸分析。</p>
<p><img src="image-20211030164712169.png" alt="image-20211030164712169"></p>
<h4 id="方法内联"><a href="#方法内联" class="headerlink" title="方法内联"></a>方法内联</h4><p>如果发现一个方法是热点方法，并且长度不太长时，会进行内联，所谓的内联就是把方法内代码拷贝、粘贴到调用者的位置，还能够进行常量折叠的优化</p>
<h4 id="字段优化"><a href="#字段优化" class="headerlink" title="字段优化"></a>字段优化</h4><h4 id="反射优化"><a href="#反射优化" class="headerlink" title="反射优化"></a>反射优化</h4><p>调用invoke前面0~15次调用使用的时MethodAccessor的NativeMethodAccessorImpl实现，当调用到第16次时，会采用运行时生成的类代替掉最初的实现，通过debug得到类名sun.reflect.GeneratedMethodAccessor1</p>


        <hr>
        <!-- Pager -->
        <ul class="pager">
          
          <li class="previous">
            <a href="/cn/nginx/nginx动静分离/" data-toggle="tooltip" data-placement="top" title="nginx动静分离">&larr; Previous Post</a>
          </li>
          
          
          <li class="next">
            <a href="/cn/nginx/nginx缓存集成/" data-toggle="tooltip" data-placement="top" title="nginx缓存集成">Next Post &rarr;</a>
          </li>
          
        </ul>

        
        <!-- tip start -->
        <!-- tip -->
<!-- tip start -->
<div class="tip">
  <p>
    
      如果您喜欢此博客或发现它对您有用，则欢迎对此发表评论。 也欢迎您共享此博客，以便更多人可以参与。 如果博客中使用的图像侵犯了您的版权，请与作者联系以将其删除。 谢谢 ！
    
  </p>
</div>
<!-- tip end -->

        <!-- tip end -->
        

        
        <hr>

        <!-- comments start -->
        <!-- 1. gitalk comment -->


<!-- 2. gitment comment -->


<!-- 3. disqus comment -->


        <!-- comments end -->
        <hr>

      </div>

      <!-- Catalog: Tabe of Content -->
      <!-- Table of Contents -->



      <!-- Sidebar Container -->
      <div class="
                col-lg-8 col-lg-offset-1
                col-md-10 col-md-offset-1
                sidebar-container">

        <!-- Featured Tags -->
        
        <section>
          <!-- no hr -->
          <h5>
            <a href="/tags/">特色标签</a>
          </h5>
          <div class="tags">
            
            <a class="tag" href="/tags/#java" title="java">java</a>
            
            <a class="tag" href="/tags/#jvm" title="jvm">jvm</a>
            
          </div>
        </section>
        

        <!-- Friends Blog -->
        
        <hr>
        <h5>链友</h5>
        <ul class="list-inline">

          
        </ul>
        
      </div>
    </div>
  </div>
</article>



<!-- anchorjs start -->
<!-- async load function -->
<!-- anchor-js, Doc:http://bryanbraun.github.io/anchorjs/ -->
<script type="text/javascript">
  // async load function
  function async (u, c) {
    var d = document,
      t = 'script',
      o = d.createElement(t),
      s = d.getElementsByTagName(t)[0];
    o.src = u;
    if (c) {
      o.addEventListener('load', function(e) {
        c(null, e);
      }, false);
    }
    s.parentNode.insertBefore(o, s);
  };
</script>
<script type="text/javascript">
  //anchor-js, Doc:http://bryanbraun.github.io/anchorjs/
  async ("https://cdn.bootcss.com/anchor-js/1.1.1/anchor.min.js", function() {
    anchors.options = {
      visible: 'hover',
      placement: 'left',
      // icon: 'ℬ'
      icon: '❡'
    };
    anchors.add().remove('.intro-header h1').remove('.subheading').remove('.sidebar-container h5');
  });
</script>
<style>
  /* place left on bigger screen */
  @media all and (min-width: 800px) {
    .anchorjs-link {
      position: absolute;
      left: -0.75em;
      font-size: 1.1em;
      margin-top: -0.1em;
    }
  }
</style>

<!-- anchorjs end -->



		<!-- Footer (contains ThemeColor、viewer) -->
		<!-- Footer -->
<footer>
  <div class="container">
    <div class="row">
      <div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1">
        <ul class="list-inline text-center">
          

          

          

          

          

          

          

          

        </ul>
        <p class="copyright text-muted">
          Copyright &copy;
          zhuang
          2021
          <br>
          Theme by
          <a target="_blank" rel="noopener" href="http://beantech.org">BeanTech</a>
          <span style="display: inline-block; margin: 0 5px;">
            <i class="fa fa-heart"></i>
          </span>
          re-Ported by
          <a target="_blank" rel="noopener" href="https://v-vincen.life/">Live My Life</a>
        </p>
      </div>
    </div>
  </div>
</footer>

<a id="rocket" href="#top" class=""></a>


  <!-- jQuery -->
  <script type="text/javascript" src="/js/jquery.min.js"></script>
  <!-- Bootstrap Core JavaScript -->
  <script type="text/javascript" src="/js/bootstrap.min.js"></script>
  <!-- Custom Theme JavaScript -->
  <script type="text/javascript" src="/js/hux-blog.min.js"></script>
  <!-- catalog -->
  <script async="true" type="text/javascript" src="/js/catalog.js"></script>
  <!-- totop(rocket) -->
  <script async="true" type="text/javascript" src="/js/totop.js"></script>

  
    <!-- Busuanzi JavaScript -->
    <script async="async" src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>
  

  
    <!-- Scroll start -->
    <script async="async" type="text/javascript" src="/js/scroll.js"></script>
    <!-- Scroll end -->
  

  

  

  
    <!-- ribbon -->
    <script type="text/javascript" src="/js/ribbonDynamic.js"></script>
  

  






  <!-- viewer start -->
  <!-- viewer start (Picture preview) -->
  
    <script async="async" type="text/javascript" src="/js/viewer/viewer.min.js"></script>
    <script async="async" type="text/javascript" src="/js/viewer/pic-viewer.js"></script>
  

  <!-- viewer end -->


<script>
  // async load function
  function async (u, c) {
    var d = document,
      t = 'script',
      o = d.createElement(t),
      s = d.getElementsByTagName(t)[0];
    o.src = u;
    if (c) {
      o.addEventListener('load', function (e) {
        c(null, e);
      }, false);
    }
    s.parentNode.insertBefore(o, s);
  }

  // fastClick.js
  async ("https://cdn.bootcss.com/fastclick/1.0.6/fastclick.min.js", function () {
    var $nav = document.querySelector("nav");
    if ($nav)
      FastClick.attach($nav);
    }
  )
</script>

<!-- Because of the native support for backtick-style fenced code blocks right within the Markdown is landed in Github Pages, From V1.6, There is no need for Highlight.js, so Huxblog drops it officially. -
https://github.com/blog/2100-github-pages-now-faster-and-simpler-with-jekyll-3-0 - https://help.github.com/articles/creating-and-highlighting-code-blocks/ -->
<!-- <script> async ("http://cdn.bootcss.com/highlight.js/8.6/highlight.min.js", function () { hljs.initHighlightingOnLoad(); }) </script> <link href="http://cdn.bootcss.com/highlight.js/8.6/styles/github.min.css" rel="stylesheet"> -->

<!-- jquery.tagcloud.js -->
<!-- <script> // only load tagcloud.js in tag.html if ($('#tag_cloud').length !== 0) { async ("http://yoursite-url/js/jquery.tagcloud.js", function () { $.fn.tagcloud.defaults = { // size: { start: 1, end: 1, unit: 'em' }, color: {
start: '#bbbbee', end: '#0085a1' } }; $('#tag_cloud a').tagcloud(); }) } </script> -->


		<!-- Search -->
		
		<div class="popup search-popup local-search-popup">
  <span class="popup-btn-close">
    ESC
  </span>
  <div class="container">
    <div class="row">
      <!-- <div class="col-md-9 col-md-offset-1"> -->
      <div class="col-lg-9 col-lg-offset-1 col-md-10 col-md-offset-1 local-search-content">

        <div class="local-search-header clearfix">

          <div class="local-search-input-wrapper">
            <span class="search-icon">
              <i class="fa fa-search fa-lg" style="margin: 25px 10px 25px 20px;"></i>
            </span>
            <input autocomplete="off" placeholder="搜索..." type="text" id="local-search-input">
          </div>
        </div>
        <div id="local-search-result"></div>
      </div>
    </div>
  </div>
</div>


  
    <script src="/js/ziploader.js"></script>
  
  <script>
    // Popup Window;
    var isfetched = false;
    var isXml = true;
    // Search DB path;
    var search_path = "search.json";
    if (search_path.length === 0) {
      search_path = "search.xml";
    } else if (/json$/i.test(search_path)) {
      isXml = false;
    }
    // monitor main search box;
    var onPopupClose = function (e) {
      $('.popup').fadeOut(300);
      $('#local-search-input').val('');
      $('.search-result-list').remove();
      $('#no-result').remove();
      $('body').css('overflow', '');
    }

    function proceedsearch() {
      $('.popup').fadeIn(300);
      var $localSearchInput = $('#local-search-input');
      $localSearchInput.attr("autocapitalize", "none");
      $localSearchInput.attr("autocorrect", "off");
      $localSearchInput.focus();
    }
    // get search zip version
    $.get('/searchVersion.json?t=' + (+new Date()), function (res) {
      if (localStorage.getItem('searchVersion') !== res) {
        localStorage.setItem('searchVersion', res);
        initSearchJson();
      }
    });

    function initSearchJson() {
      initLoad(['/search.flv'], {
        loadOptions: {
          success: function (obj) {
            localStorage.setItem('searchJson', obj['search.json'])
          },
          error: function (e) {
            return console.log(e)
          }
        },
        returnOptions: {
          'json': TYPE_TEXT
        },
        mimeOptions: {
          'json': 'application/json'
        }
      })
    }
    // search function;
    var searchFunc = function (search_id, content_id) {
      'use strict';
      isfetched = true;
      var datas = JSON.parse(localStorage.getItem('searchJson'));
      // console.log(search_id)
      var input = document.getElementById(search_id);
      var resultContent = document.getElementById(content_id);
      var inputEventFunction = function () {
        var searchText = input.value.trim().toLowerCase();
        var keywords = searchText.split(/[\s\-]+/);
        if (keywords.length > 1) {
          keywords.push(searchText);
        }
        var resultItems = [];
        if (searchText.length > 0) {
          // perform local searching
          datas.forEach(function (data) {
            var isMatch = false;
            var hitCount = 0;
            var searchTextCount = 0;
            var title = data.title
              ? data.title.trim()
              : '';
            var titleInLowerCase = title.toLowerCase();
            var content = data.content
              ? data.content.trim().replace(/<[^>]+>/g, "")
              : '';
            var contentInLowerCase = content.toLowerCase();
            var articleUrl = decodeURIComponent(data.url);

            var date = data.date;
            var dateTime = date.replace(/T/, " ").replace(/.000Z/, "");
            var imgUrl = data.header_img;
            


            var indexOfTitle = [];
            var indexOfContent = [];
            // only match articles with not empty titles
            keywords.forEach(function (keyword) {
              function getIndexByWord(word, text, caseSensitive) {
                var wordLen = word.length;
                if (wordLen === 0) {
                  return [];
                }
                var startPosition = 0,
                  position = [],
                  index = [];
                if (!caseSensitive) {
                  text = text.toLowerCase();
                  word = word.toLowerCase();
                }
                while ((position = text.indexOf(word, startPosition)) > -1) {
                  index.push({position: position, word: word});
                  startPosition = position + wordLen;
                }
                return index;
              }
              indexOfTitle = indexOfTitle.concat(getIndexByWord(keyword, titleInLowerCase, false));
              indexOfContent = indexOfContent.concat(getIndexByWord(keyword, contentInLowerCase, false));
            });
            if (indexOfTitle.length > 0 || indexOfContent.length > 0) {
              isMatch = true;
              hitCount = indexOfTitle.length + indexOfContent.length;
            }
            // show search results
            if (isMatch) {
              // sort index by position of keyword
              [indexOfTitle, indexOfContent].forEach(function (index) {
                index.sort(function (itemLeft, itemRight) {
                  if (itemRight.position !== itemLeft.position) {
                    return itemRight.position - itemLeft.position;
                  } else {
                    return itemLeft.word.length - itemRight.word.length;
                  }
                });
              });
              // merge hits into slices
              function mergeIntoSlice(text, start, end, index) {
                var item = index[index.length - 1];
                var position = item.position;
                var word = item.word;
                var hits = [];
                var searchTextCountInSlice = 0;
                while (position + word.length <= end && index.length != 0) {
                  if (word === searchText) {
                    searchTextCountInSlice++;
                  }
                  hits.push({position: position, length: word.length});
                  var wordEnd = position + word.length;
                  // move to next position of hit
                  index.pop();
                  while (index.length != 0) {
                    item = index[index.length - 1];
                    position = item.position;
                    word = item.word;
                    if (wordEnd > position) {
                      index.pop();
                    } else {
                      break;
                    }
                  }
                }
                searchTextCount += searchTextCountInSlice;
                return {hits: hits, start: start, end: end, searchTextCount: searchTextCountInSlice};
              }
              var slicesOfTitle = [];
              if (indexOfTitle.length != 0) {
                slicesOfTitle.push(mergeIntoSlice(title, 0, title.length, indexOfTitle));
              }
              var slicesOfContent = [];
              while (indexOfContent.length != 0) {
                var item = indexOfContent[indexOfContent.length - 1];
                var position = item.position;
                var word = item.word;
                // cut out 100 characters
                var start = position - 20;
                var end = position + 80;
                if (start < 0) {
                  start = 0;
                }
                if (end < position + word.length) {
                  end = position + word.length;
                }
                if (end > content.length) {
                  end = content.length;
                }
                slicesOfContent.push(mergeIntoSlice(content, start, end, indexOfContent));
              }
              // sort slices in content by search text's count and hits' count
              slicesOfContent.sort(function (sliceLeft, sliceRight) {
                if (sliceLeft.searchTextCount !== sliceRight.searchTextCount) {
                  return sliceRight.searchTextCount - sliceLeft.searchTextCount;
                } else if (sliceLeft.hits.length !== sliceRight.hits.length) {
                  return sliceRight.hits.length - sliceLeft.hits.length;
                } else {
                  return sliceLeft.start - sliceRight.start;
                }
              });
              // select top N slices in content
              var upperBound = parseInt('1');
              if (upperBound >= 0) {
                slicesOfContent = slicesOfContent.slice(0, upperBound);
              }
              // highlight title and content
              function highlightKeyword(text, slice) {
                var result = '';
                var prevEnd = slice.start;
                slice.hits.forEach(function (hit) {
                  result += text.substring(prevEnd, hit.position);
                  var end = hit.position + hit.length;
                  result += '<b class="search-keyword">' + text.substring(hit.position, end) + '</b>';
                  prevEnd = end;
                });
                result += text.substring(prevEnd, slice.end);
                return result;
              }
              var resultItem = '';

              // if (slicesOfTitle.length != 0) {   resultItem += "<li><a target='_blank' href='" + articleUrl + "' class='search-result-title'>" + highlightKeyword(title, slicesOfTitle[0]) + "</a>"; } else {   resultItem += "<li><a target='_blank' href='" +
              // articleUrl + "' class='search-result-title'>" + title + "</a>"; } slicesOfContent.forEach(function (slice) {   resultItem += "<a target='_blank' href='" + articleUrl + "'><p class=\"search-result\">" + highlightKeyword(content, slice) +
              // "...</p></a>"; }); resultItem += "</li>";

              if (slicesOfTitle.length != 0) {
                resultItem += "<a target='_blank' href='" + articleUrl + "' class='search-result'><div class='search-result-left'><div class='search-result-title'>" + highlightKeyword(title, slicesOfTitle[0]) + "</div><time class='search-result-date'>" + dateTime + "</time>";
              } else {
                resultItem += "<a target='_blank' href='" + articleUrl + "' class='search-result'><div class='search-result-left'><div class='search-result-title'>" + title + "</div><time class='search-result-date'>" + dateTime + "</time>";
              }
              slicesOfContent.forEach(function (slice) {
                resultItem += "<p class=\"search-result-content\">" + highlightKeyword(content, slice) + "...</p>";
              });
              resultItem += "</div><div class='search-result-right'><img class='media-image' src='" + imgUrl + "' width='64px' height='48px'></img></div></a>";

              resultItems.push({item: resultItem, searchTextCount: searchTextCount, hitCount: hitCount, id: resultItems.length});
            }
          })
        };

        if (keywords.length === 1 && keywords[0] === "") {
          resultContent.innerHTML = '<div id="no-result"></div>'
        } else if (resultItems.length === 0) {
          resultContent.innerHTML = '<div id="no-result"></div>'
        } else {
          resultItems.sort(function (resultLeft, resultRight) {
            if (resultLeft.searchTextCount !== resultRight.searchTextCount) {
              return resultRight.searchTextCount - resultLeft.searchTextCount;
            } else if (resultLeft.hitCount !== resultRight.hitCount) {
              return resultRight.hitCount - resultLeft.hitCount;
            } else {
              return resultRight.id - resultLeft.id;
            }
          });
          var searchResultList = '<div class=\"search-result-list\">';
          resultItems.forEach(function (result) {
            searchResultList += result.item;
          })
          searchResultList += "</div>";
          resultContent.innerHTML = searchResultList;
        }
      }
      if ('auto' === 'auto') {
        input.addEventListener('input', inputEventFunction);
      } else {
        $('.search-icon').click(inputEventFunction);
        input.addEventListener('keypress', function (event) {
          if (event.keyCode === 13) {
            inputEventFunction();
          }
        });
      }
      // remove loading animation
      $('body').css('overflow', '');
      proceedsearch();
    }
    // handle and trigger popup window;
    $('.popup-trigger').click(function (e) {
      e.stopPropagation();
      if (isfetched === false) {
        searchFunc('local-search-input', 'local-search-result');
      } else {
        proceedsearch();
      };
    });
    $('.popup-btn-close').click(onPopupClose);
    $('.popup').click(function (e) {
      e.stopPropagation();
    });
    $(document).on('keyup', function (event) {
      var shouldDismissSearchPopup = event.which === 27 && $('.search-popup').is(':visible');
      if (shouldDismissSearchPopup) {
        onPopupClose();
      }
    });

    document.addEventListener('mouseup', (e) => {
      var _con = document.querySelector(".local-search-content");
      if (_con) {
        if (!_con.contains(e.target)) {
          onPopupClose();
        }
      }
    });
  </script>


		
	<script type="text/x-mathjax-config">
    MathJax.Hub.Config({
        tex2jax: {
            inlineMath: [ ["$","$"], ["\\(","\\)"] ],
            skipTags: ['script', 'noscript', 'style', 'textarea', 'pre', 'code'],
            processEscapes: true
        }
    });
    MathJax.Hub.Queue(function() {
        var all = MathJax.Hub.getAllJax();
        for (var i = 0; i < all.length; ++i)
            all[i].SourceElement().parentNode.className += ' has-jax';
    });
</script>
<script src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
</body>
</html>
